CogEngine: Improve Plot window

- Save plotted entries between sessions
- Add more options (autofit padding, num recorded values, record values when paused
- Fix dragging the mouse on a different window over the graph pausing the graph
This commit is contained in:
Arnaud Jamin
2025-01-24 00:57:24 -05:00
parent f7e63c3823
commit aca54cbe9d
6 changed files with 844 additions and 646 deletions
@@ -17,6 +17,11 @@ void FCogEngineWindow_Plots::Initialize()
Config = GetConfig<UCogEngineConfig_Plots>();
if (Config != nullptr)
{
RefreshPlotSettings();
}
FCogDebugPlot::Clear();
}
@@ -34,8 +39,9 @@ void FCogEngineWindow_Plots::ResetConfig()
Super::ResetConfig();
Config->Reset();
}
RefreshPlotSettings();
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Plots::RenderTick(float DeltaTime)
@@ -49,23 +55,6 @@ void FCogEngineWindow_Plots::RenderContent()
{
Super::RenderContent();
TArray<FCogDebugPlotEntry*> VisiblePlots;
for (FCogDebugPlotEntry& Plot : FCogDebugPlot::Plots)
{
if (Plot.YAxis != ImAxis_COUNT && Plot.GraphIndex != INDEX_NONE)
{
VisiblePlots.Add(&Plot);
}
}
for (FCogDebugPlotEntry& Event : FCogDebugPlot::Events)
{
if (Event.YAxis != ImAxis_COUNT && Event.GraphIndex != INDEX_NONE)
{
VisiblePlots.Add(&Event);
}
}
RenderMenu();
if (Config->DockEntries)
@@ -86,7 +75,7 @@ void FCogEngineWindow_Plots::RenderContent()
RenderAllEntriesNames(ImVec2(0, -1));
ImGui::TableNextColumn();
RenderPlots(VisiblePlots);
RenderPlots();
ImGui::EndTable();
}
@@ -94,12 +83,19 @@ void FCogEngineWindow_Plots::RenderContent()
}
else
{
RenderPlots(VisiblePlots);
RenderPlots();
}
bApplyTimeScale = false;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Plots::RefreshPlotSettings()
{
FCogDebugPlot::SetNumRecordedValues(Config->NumRecordedValues);
FCogDebugPlot::RecordValuesWhenPause = Config->RecordValuesWhenPaused;
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Plots::RenderMenu()
{
@@ -116,33 +112,41 @@ void FCogEngineWindow_Plots::RenderMenu()
if (ImGui::BeginMenu("Options"))
{
if (ImGui::MenuItem("Reset"))
{
FCogDebugPlot::Pause = false;
FCogDebugPlot::Reset();
ResetConfig();
}
ImGui::Separator();
FCogWindowWidgets::SetNextItemToShortWidth();
ImGui::SliderInt("Num graphs", &Config->NumGraphs, 1, UCogEngineConfig_Plots::MaxNumGraphs);
FCogWindowWidgets::SetNextItemToShortWidth();
if (ImGui::SliderInt("Num Graphs", &Config->NumGraphs, 1, 5))
ImGui::SliderInt("Num Y axis", &Config->NumYAxis, 1, 3);
FCogWindowWidgets::SetNextItemToShortWidth();
if (ImGui::SliderFloat("Time range", &Config->TimeRange, 1.0f, 100.0f, "%0.0f"))
{
bApplyTimeScale = true;
}
FCogWindowWidgets::SetNextItemToShortWidth();
ImGui::SliderInt("Num YAxis", &Config->NumYAxis, 0, 3);
FCogWindowWidgets::SetNextItemToShortWidth();
if (ImGui::SliderFloat("Time range", &Config->TimeRange, 1.0f, 100.0f, "%0.1f"))
if (ImGui::SliderInt("Num recorded values", &Config->NumRecordedValues, 100, 10000))
{
bApplyTimeScale = true;
Config->NumRecordedValues = (Config->NumRecordedValues / 100) * 100;
}
if (ImGui::IsItemDeactivatedAfterEdit())
{
RefreshPlotSettings();
}
FCogWindowWidgets::SetNextItemToShortWidth();
ImGui::SliderFloat("Auto-fit padding", &Config->AutoFitPadding, 0.0f, 0.2f, "%0.2f");
FCogWindowWidgets::SetNextItemToShortWidth();
ImGui::SliderFloat("Drag pause sensitivity", &Config->DragPauseSensitivity, 1.0f, 50.0f, "%0.0f");
ImGui::Checkbox("Record values when paused", &Config->RecordValuesWhenPaused);
if (ImGui::IsItemDeactivatedAfterEdit())
{
RefreshPlotSettings();
}
FCogWindowWidgets::SetNextItemToShortWidth();
ImGui::Checkbox("Show time bar at game time", &Config->ShowTimeBarAtGameTime);
@@ -159,6 +163,16 @@ void FCogEngineWindow_Plots::RenderMenu()
FCogImguiHelper::ColorEdit4("Pause background color", Config->PauseBackgroundColor, ColorEditFlags);
ImGui::SetItemTooltip("Background color of the plot when paused.");
ImGui::Separator();
if (ImGui::MenuItem("Reset Settings"))
{
FCogDebugPlot::Pause = false;
FCogDebugPlot::Reset();
ResetConfig();
bApplyTimeScale = true;
}
ImGui::EndMenu();
}
@@ -174,20 +188,31 @@ void FCogEngineWindow_Plots::RenderMenu()
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Plots::RenderEntryName(const int Index, FCogDebugPlotEntry& Entry)
void FCogEngineWindow_Plots::RenderEntryName(const int Index, FCogDebugHistory& Entry)
{
ImGui::PushID(Index);
const bool IsAssignedToRow = Entry.GraphIndex != INDEX_NONE;
if (ImGui::Selectable(TCHAR_TO_ANSI(*Entry.Name.ToString()), IsAssignedToRow, ImGuiSelectableFlags_AllowDoubleClick))
bool IsAssignedToGraph = false;
for (int32 i = 0; i < UCogEngineConfig_Plots::MaxNumGraphs; ++i)
{
if (IsAssignedToRow)
FCogEngineConfig_Plots_GraphInfo& GraphInfo = Config->Graphs[i];
if (GraphInfo.Entries.ContainsByPredicate([Entry](const auto& InEntry) { return InEntry.Name == Entry.Name; }))
{
Entry.ResetGraphAndAxis();
IsAssignedToGraph = true;
break;
}
}
if (ImGui::Selectable(TCHAR_TO_ANSI(*Entry.Name.ToString()), IsAssignedToGraph, ImGuiSelectableFlags_AllowDoubleClick))
{
if (IsAssignedToGraph)
{
UnassignToGraphAndAxis(Entry.Name);
}
else
{
Entry.AssignGraphAndAxis(0, ImAxis_Y1);
AssignToGraphAndAxis(Entry.Name, 0, ImAxis_Y1);
}
}
@@ -205,50 +230,46 @@ void FCogEngineWindow_Plots::RenderEntryName(const int Index, FCogDebugPlotEntry
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Plots::RenderAllEntriesNames(const ImVec2& InSize)
{
const int32 Indent = ImGui::GetFontSize() * 0.5f;
if (ImGui::BeginChild("Entries", InSize))
{
if (Config->DockEntries)
{
ImGui::Indent(6);
}
int Index = 0;
if (FCogWindowWidgets::DarkCollapsingHeader("Events", ImGuiTreeNodeFlags_DefaultOpen))
{
ImGui::Indent(Indent);
if (FCogDebugPlot::Events.IsEmpty())
{
ImGui::TextDisabled("No event added yet");
}
else
{
for (FCogDebugPlotEntry& Event : FCogDebugPlot::Events)
for (auto& kv : FCogDebugPlot::Events)
{
RenderEntryName(Index, Event);
RenderEntryName(Index, kv.Value);
Index++;
}
}
ImGui::Unindent(Indent);
}
if (FCogWindowWidgets::DarkCollapsingHeader("Plots", ImGuiTreeNodeFlags_DefaultOpen))
{
if (FCogDebugPlot::Plots.IsEmpty())
ImGui::Indent(Indent);
if (FCogDebugPlot::Values.IsEmpty())
{
ImGui::TextDisabled("No plot added yet");
}
else
{
for (FCogDebugPlotEntry& Plot : FCogDebugPlot::Plots)
for (auto& kv : FCogDebugPlot::Values)
{
RenderEntryName(Index, Plot);
RenderEntryName(Index, kv.Value);
Index++;
}
}
}
if (Config->DockEntries)
{
ImGui::Unindent();
ImGui::Unindent(Indent);
}
}
ImGui::EndChild();
@@ -257,17 +278,14 @@ void FCogEngineWindow_Plots::RenderAllEntriesNames(const ImVec2& InSize)
{
if (const ImGuiPayload* Payload = ImGui::AcceptDragDropPayload("DragAndDrop"))
{
if (FCogDebugPlotEntry* Plot = FCogDebugPlot::FindEntry(FName((const char*)Payload->Data)))
{
Plot->ResetGraphAndAxis();
}
UnassignToGraphAndAxis(GetDroppedEntryName(Payload));
}
ImGui::EndDragDropTarget();
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Plots::RenderPlots(const TArray<FCogDebugPlotEntry*>& VisiblePlots) const
void FCogEngineWindow_Plots::RenderPlots()
{
if (ImGui::BeginChild("Graph", ImVec2(0, -1)))
{
@@ -281,45 +299,66 @@ void FCogEngineWindow_Plots::RenderPlots(const TArray<FCogDebugPlotEntry*>& Visi
ImPlot::PushStyleColor(ImPlotCol_PlotBg, FCogImguiHelper::ToImVec4(Config->PauseBackgroundColor));
}
ImPlot::PushStyleVar(ImPlotStyleVar_FitPadding, ImVec2(0.0f, Config->AutoFitPadding));
if (ImPlot::BeginSubplots("", Config->NumGraphs, 1, ImVec2(-1, -1), SubplotsFlags, RowRatios, ColRatios))
{
for (int PlotIndex = 0; PlotIndex < Config->NumGraphs; ++PlotIndex)
for (int32 GraphIndex = 0; GraphIndex < Config->NumGraphs && GraphIndex < UCogEngineConfig_Plots::MaxNumGraphs; ++GraphIndex)
{
ImGui::PushID(GraphIndex);
FCogEngineConfig_Plots_GraphInfo& GraphInfo = Config->Graphs[GraphIndex];
if (ImPlot::BeginPlot("##Plot", ImVec2(-1, 250)))
{
ImPlotAxisFlags HasPlotOnAxisY1 = false;
ImPlotAxisFlags HasPlotOnAxisY2 = false;
ImPlotAxisFlags HasPlotOnAxisY3 = false;
for (const FCogDebugPlotEntry* PlotPtr : VisiblePlots)
{
HasPlotOnAxisY1 |= PlotPtr->YAxis == ImAxis_Y1 && PlotPtr->GraphIndex == PlotIndex;
HasPlotOnAxisY2 |= PlotPtr->YAxis == ImAxis_Y2 && PlotPtr->GraphIndex == PlotIndex;
HasPlotOnAxisY3 |= PlotPtr->YAxis == ImAxis_Y3 && PlotPtr->GraphIndex == PlotIndex;
}
ImPlot::SetupAxis(ImAxis_X1, nullptr, ImPlotAxisFlags_NoTickLabels | ImPlotAxisFlags_NoGridLines);
if (Config->NumYAxis > 0)
{
ImPlot::SetupAxis(ImAxis_Y1, HasPlotOnAxisY1 ? "" : "[drop here]", (HasPlotOnAxisY1 ? ImPlotAxisFlags_None : (ImPlotAxisFlags_NoTickLabels | ImPlotAxisFlags_NoGridLines)) | ImPlotAxisFlags_AutoFit);
}
if (Config->NumYAxis > 1)
{
ImPlot::SetupAxis(ImAxis_Y2, HasPlotOnAxisY2 ? "" : "[drop here]", (HasPlotOnAxisY2 ? ImPlotAxisFlags_None : (ImPlotAxisFlags_NoTickLabels | ImPlotAxisFlags_NoGridLines)) | ImPlotAxisFlags_AutoFit | ImPlotAxisFlags_Opposite);
}
if (Config->NumYAxis > 2)
{
ImPlot::SetupAxis(ImAxis_Y3, HasPlotOnAxisY3 ? "" : "[drop here]", (HasPlotOnAxisY3 ? ImPlotAxisFlags_None : (ImPlotAxisFlags_NoTickLabels | ImPlotAxisFlags_NoGridLines)) | ImPlotAxisFlags_AutoFit | ImPlotAxisFlags_Opposite);
}
//--------------------------------------------------------------------------------------------------
// Set the initial X axis range. After, it is automatically updated to move with the current time.
//--------------------------------------------------------------------------------------------------
ImPlot::SetupAxisLimits(ImAxis_X1, 0, Config->TimeRange, ImGuiCond_Appearing);
//--------------------------------------------------------------------------------------------------
// Setup the Y axis
//--------------------------------------------------------------------------------------------------
for (int32 YAxisIndex = 0; YAxisIndex <= (ImAxis_Y3 - ImAxis_Y1); ++YAxisIndex)
{
const ImAxis YAxis = ImAxis_Y1 + YAxisIndex;
bool IsAssigned = false;
int32 YMax = 0;
for (const FCogEngineConfig_Plots_GraphEntryInfo& GraphEntry : GraphInfo.Entries)
{
IsAssigned |= GraphEntry.YAxis == YAxis;
if (FCogDebugEventHistory* EventHistory = FCogDebugPlot::Events.Find(GraphEntry.Name))
{
YMax = FMath::Max(FMath::Max(5, YMax), EventHistory->MaxRow);
}
}
const bool IsAxisVisible = IsAssigned || (YAxisIndex < Config->NumYAxis);
if (IsAxisVisible)
{
ImPlotAxisFlags Flags = IsAssigned ? ImPlotAxisFlags_NoGridLines | ImPlotAxisFlags_AutoFit
: ImPlotAxisFlags_NoTickLabels | ImPlotAxisFlags_NoGridLines | ImPlotAxisFlags_AutoFit;
if (YAxisIndex > 0)
{
Flags |= ImPlotAxisFlags_Opposite;
}
ImPlot::SetupAxis(YAxis, IsAssigned || (Config->NumYAxis == 1) ? "" : "[drop here]", Flags);
//--------------------------------------------------------------------------------
// Set the Y axis limit for Events.
//--------------------------------------------------------------------------------
if (YMax > 0)
{
ImPlot::SetupAxisLimits(YAxis, 0, YMax, ImGuiCond_Always);
}
}
}
const ImPlotRange& PlotRange = ImPlot::GetCurrentPlot()->Axes[ImAxis_X1].Range;
const float TimeRange = PlotRange.Max - PlotRange.Min;
@@ -331,7 +370,7 @@ void FCogEngineWindow_Plots::RenderPlots(const TArray<FCogDebugPlotEntry*>& Visi
const float Time = GetWorld() ? GetWorld()->GetTimeSeconds() : 0.0;
//------------------------------------------------------------------
// Setup all the Z and Y axis limits. Must be done before calling
// Setup all the X axis limits. Must be done before calling
// ImPlot::GetPlotPos or ImPlot::GetPlotSize as it calls SetupLock()
//------------------------------------------------------------------
{
@@ -347,23 +386,6 @@ void FCogEngineWindow_Plots::RenderPlots(const TArray<FCogDebugPlotEntry*>& Visi
{
ImPlot::SetupAxisLimits(ImAxis_X1, Time - Config->TimeRange, Time, ImGuiCond_Always);
}
//--------------------------------------------------------------------------------
// Set the Y axis limit for Events.
//--------------------------------------------------------------------------------
for (const FCogDebugPlotEntry* PlotPtr : VisiblePlots)
{
if (PlotPtr == nullptr)
{ continue; }
if (PlotPtr->GraphIndex != PlotIndex)
{ continue; }
if (PlotPtr->IsEventPlot)
{
ImPlot::SetupAxisLimits(PlotPtr->YAxis, 0, PlotPtr->MaxRow + 2, ImGuiCond_Always);
}
}
}
const ImVec2 PlotMin = ImPlot::GetPlotPos();
@@ -373,17 +395,21 @@ void FCogEngineWindow_Plots::RenderPlots(const TArray<FCogDebugPlotEntry*>& Visi
//----------------------------------------------------------------
// Pause the scrolling if the user drag inside
//----------------------------------------------------------------
const ImVec2 Mouse = ImGui::GetMousePos();
if (Mouse.x > PlotMin.x
&& Mouse.y > PlotMin.y
&& Mouse.x < PlotMax.x
&& Mouse.y < PlotMax.y
&& ImGui::GetDragDropPayload() == nullptr)
if (ImGui::IsWindowFocused())
{
const ImVec2 Drag = ImGui::GetMouseDragDelta(0);
if (FMath::Abs(Drag.x) > Config->DragPauseSensitivity)
const ImVec2 Mouse = ImGui::GetMousePos();
if (Mouse.x > PlotMin.x
&& Mouse.y > PlotMin.y
&& Mouse.x < PlotMax.x
&& Mouse.y < PlotMax.y
&& ImGui::GetDragDropPayload() == nullptr)
{
FCogDebugPlot::Pause = true;
const ImVec2 Drag = ImGui::GetMouseDragDelta(0);
if (FMath::Abs(Drag.x) > Config->DragPauseSensitivity)
{
FCogDebugPlot::Pause = true;
}
}
}
@@ -417,43 +443,46 @@ void FCogEngineWindow_Plots::RenderPlots(const TArray<FCogDebugPlotEntry*>& Visi
}
//-----------------------------------------------------------
// Draw all the plots assigned to this row
// Draw all the plots assigned to this graph
//-----------------------------------------------------------
for (FCogDebugPlotEntry* PlotPtr : VisiblePlots)
for (FCogEngineConfig_Plots_GraphEntryInfo& Entry : GraphInfo.Entries)
{
if (PlotPtr == nullptr)
{ continue; }
FCogDebugHistory* History = FCogDebugPlot::FindEntry(Entry.Name);
if (History == nullptr)
{
continue;
}
FCogDebugPlotEntry& Plot = *PlotPtr;
if (Plot.GraphIndex != PlotIndex)
{ continue; }
ImPlot::SetAxis(Plot.YAxis);
ImPlot::SetAxis(Entry.YAxis);
ImPlot::SetNextLineStyle(IMPLOT_AUTO_COL);
const auto Label = StringCast<ANSICHAR>(*Plot.Name.ToString());
const auto Label = StringCast<ANSICHAR>(*Entry.Name.ToString());
//-------------------------------------------------------
// Plot Events
//-------------------------------------------------------
if (Plot.IsEventPlot)
switch (History->Type)
{
RenderEvents(Plot, Label.Get(), PlotMin, PlotMax);
}
//-------------------------------------------------------
// Plot Values
//-------------------------------------------------------
else if (Plot.Values.empty() == false)
{
RenderValues(Plot, Label.Get());
case FCogDebugHistoryType::Event:
{
RenderEvents(*static_cast<FCogDebugEventHistory*>(History), Label.Get(), PlotMin, PlotMax);
break;
}
case FCogDebugHistoryType::Value:
{
RenderValues(*static_cast<FCogDebugValueHistory*>(History), Label.Get());
break;
}
}
//-------------------------------------------------------
// Allow legend item labels to be drag and drop sources
//-------------------------------------------------------
if (ImPlot::BeginDragDropSourceItem(Label.Get()))
{
const auto EntryName = StringCast<ANSICHAR>(*Plot.Name.ToString());
const auto EntryName = StringCast<ANSICHAR>(*Entry.Name.ToString());
ImGui::SetDragDropPayload("DragAndDrop", EntryName.Get(), EntryName.Length() + 1);
ImGui::TextUnformatted(EntryName.Get());
ImPlot::EndDragDropSource();
@@ -467,10 +496,7 @@ void FCogEngineWindow_Plots::RenderPlots(const TArray<FCogDebugPlotEntry*>& Visi
{
if (const ImGuiPayload* Payload = ImGui::AcceptDragDropPayload("DragAndDrop"))
{
if (FCogDebugPlotEntry* Plot = FCogDebugPlot::FindEntry(FName((const char*)Payload->Data)))
{
Plot->AssignGraphAndAxis(PlotIndex, ImAxis_Y1);
}
AssignToGraphAndAxis(GetDroppedEntryName(Payload), GraphIndex, ImAxis_Y1);
}
ImPlot::EndDragDropTarget();
}
@@ -478,16 +504,14 @@ void FCogEngineWindow_Plots::RenderPlots(const TArray<FCogDebugPlotEntry*>& Visi
//-------------------------------------------------------
// Allow each y-axis to be a drag and drop target
//-------------------------------------------------------
for (int y = ImAxis_Y1; y <= ImAxis_Y3; ++y)
for (int32 YAxisIndex = 0; YAxisIndex < Config->NumYAxis; ++YAxisIndex)
{
if (ImPlot::BeginDragDropTargetAxis(y))
const ImAxis YAxis = ImAxis_Y1 + YAxisIndex;
if (ImPlot::BeginDragDropTargetAxis(YAxis))
{
if (const ImGuiPayload* Payload = ImGui::AcceptDragDropPayload("DragAndDrop"))
{
if (FCogDebugPlotEntry* Plot = FCogDebugPlot::FindEntry(FName((const char*)Payload->Data)))
{
Plot->AssignGraphAndAxis(PlotIndex, y);
}
AssignToGraphAndAxis(GetDroppedEntryName(Payload), GraphIndex, YAxis);
}
ImPlot::EndDragDropTarget();
}
@@ -500,20 +524,21 @@ void FCogEngineWindow_Plots::RenderPlots(const TArray<FCogDebugPlotEntry*>& Visi
{
if (const ImGuiPayload* Payload = ImGui::AcceptDragDropPayload("DragAndDrop"))
{
if (FCogDebugPlotEntry* Plot = FCogDebugPlot::FindEntry(FName((const char*)Payload->Data)))
{
Plot->AssignGraphAndAxis(PlotIndex, ImAxis_Y1);
}
AssignToGraphAndAxis(GetDroppedEntryName(Payload), GraphIndex, ImAxis_Y1);
}
ImPlot::EndDragDropTarget();
}
ImPlot::EndPlot();
}
ImGui::PopID();
}
ImPlot::EndSubplots();
}
ImPlot::PopStyleVar();
if (PushPlotBgStyle)
{
ImPlot::PopStyleColor();
@@ -523,8 +548,13 @@ void FCogEngineWindow_Plots::RenderPlots(const TArray<FCogDebugPlotEntry*>& Visi
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Plots::RenderValues(FCogDebugPlotEntry& Entry, const char* Label) const
void FCogEngineWindow_Plots::RenderValues(FCogDebugValueHistory& Entry, const char* Label) const
{
if (Entry.Values.empty())
{
return;
}
//----------------------------------------------------------------
// Value at cursor tooltip
//----------------------------------------------------------------
@@ -568,7 +598,7 @@ void FCogEngineWindow_Plots::RenderValues(FCogDebugPlotEntry& Entry, const char*
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Plots::RenderEvents(FCogDebugPlotEntry& Entry, const char* Label, const ImVec2& PlotMin, const ImVec2& PlotMax) const
void FCogEngineWindow_Plots::RenderEvents(FCogDebugEventHistory& Entry, const char* Label, const ImVec2& PlotMin, const ImVec2& PlotMax) const
{
const ImVec2 Mouse = ImGui::GetMousePos();
ImDrawList* PlotDrawList = ImPlot::GetPlotDrawList();
@@ -581,7 +611,7 @@ void FCogEngineWindow_Plots::RenderEvents(FCogDebugPlotEntry& Entry, const char*
ImVector<ImVec2> DummyData;
DummyData.push_back(ImVec2(0, 0));
DummyData.push_back(ImVec2(0, 8));
ImPlot::PlotLine(Label, &DummyData[0].x, &DummyData[0].y, DummyData.size(), Entry.ValueOffset, 2 * sizeof(float));
ImPlot::PlotLine(Label, &DummyData[0].x, &DummyData[0].y, DummyData.size(), Entry.EventOffset, 2 * sizeof(float));
const FCogDebugPlotEvent* HoveredEvent = nullptr;
@@ -641,7 +671,7 @@ void FCogEngineWindow_Plots::RenderEvents(FCogDebugPlotEntry& Entry, const char*
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Plots::RenderEventTooltip(const FCogDebugPlotEvent* HoveredEvent, const FCogDebugPlotEntry& Entry)
void FCogEngineWindow_Plots::RenderEventTooltip(const FCogDebugPlotEvent* HoveredEvent, const FCogDebugHistory& Entry)
{
if (ImPlot::IsPlotHovered() && HoveredEvent != nullptr)
{
@@ -716,3 +746,54 @@ void FCogEngineWindow_Plots::RenderEventTooltip(const FCogDebugPlotEvent* Hovere
}
}
}
//--------------------------------------------------------------------------------------------------------------------------
FName FCogEngineWindow_Plots::GetDroppedEntryName(const ImGuiPayload* Payload)
{
return FName(static_cast<const char*>(Payload->Data));
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Plots::AssignToGraphAndAxis(const FName InName, const int32 InGraphIndex, const ImAxis InYAxis)
{
UnassignToGraphAndAxis(InName);
FCogDebugHistory* History = FCogDebugPlot::FindEntry(InName);
if (History == nullptr)
{ return; }
History->GraphIndex = InGraphIndex;
FCogEngineConfig_Plots_GraphInfo& GraphInfo = Config->Graphs[InGraphIndex];
FCogEngineConfig_Plots_GraphEntryInfo* CorrespondingEntry = GraphInfo.Entries.FindByPredicate(
[InName](const auto& InEntry) { return InEntry.Name == InName; });
if (CorrespondingEntry == nullptr)
{
GraphInfo.Entries.Add({InName, InYAxis});
}
else
{
CorrespondingEntry->YAxis = InYAxis;
}
}
//--------------------------------------------------------------------------------------------------------------------------
void FCogEngineWindow_Plots::UnassignToGraphAndAxis(const FName InName)
{
const FCogDebugHistory* History = FCogDebugPlot::FindEntry(InName);
if (History == nullptr)
{ return; }
FCogEngineConfig_Plots_GraphInfo& GraphInfo = Config->Graphs[History->GraphIndex];
const int32 Index = GraphInfo.Entries.IndexOfByPredicate([InName](const auto& InEntry) { return InEntry.Name == InName; });
if (Index != INDEX_NONE)
{
GraphInfo.Entries.RemoveAt(Index);
}
}