From 119d04ac3a7c0ac5e55e5a2f09badf4ebc3b3bc2 Mon Sep 17 00:00:00 2001 From: epezent Date: Wed, 3 Mar 2021 08:28:23 -0600 Subject: [PATCH] add previous plot and such --- implot.cpp | 66 ++++++++++++++++++++++++++------------ implot_demo.cpp | 82 +++++++++++++++++++++++++---------------------- implot_internal.h | 5 ++- 3 files changed, 93 insertions(+), 60 deletions(-) diff --git a/implot.cpp b/implot.cpp index 021d672..b993b2b 100644 --- a/implot.cpp +++ b/implot.cpp @@ -384,6 +384,7 @@ void SetCurrentContext(ImPlotContext* ctx) { void Initialize(ImPlotContext* ctx) { Reset(ctx); + ctx->CurrentPlot = ctx->PreviousPlot = NULL; ctx->Colormap = GetColormap(ImPlotColormap_Default, &ctx->ColormapSize); } @@ -417,6 +418,7 @@ void Reset(ImPlotContext* ctx) { ctx->DigitalPlotItemCnt = 0; ctx->DigitalPlotOffset = 0; // nullify plot + ctx->PreviousPlot = ctx->CurrentPlot; ctx->CurrentPlot = NULL; ctx->CurrentItem = NULL; ctx->PreviousItem = NULL; @@ -436,6 +438,10 @@ ImPlotPlot* GetCurrentPlot() { return GImPlot->CurrentPlot; } +ImPlotPlot* GetCurrentOrPreviousPlot() { + return GImPlot->CurrentPlot == NULL ? GImPlot->PreviousPlot : GImPlot->CurrentPlot; +} + void BustPlotCache() { GImPlot->Plots.Clear(); } @@ -2914,27 +2920,37 @@ bool DragPoint(const char* id, double* x, double* y, bool show_label, const ImVe bool BeginDragDropTargetEx(int id, const ImRect& rect) { ImGuiContext& G = *GImGui; const ImGuiID ID = G.CurrentWindow->GetID(id); - if (ImGui::ItemAdd(rect, ID, &rect) && - ImGui::BeginDragDropTarget()) + if (ImGui::ItemAdd(rect, ID, &rect) && ImGui::BeginDragDropTarget()) return true; return false; } bool BeginDragDropTarget() { - return BeginDragDropTargetEx(IMPLOT_ID_PLT, GImPlot->CurrentPlot->PlotRect); + ImPlotPlot* plt = GetCurrentOrPreviousPlot(); + if (plt == NULL) + return false; + return BeginDragDropTargetEx(IMPLOT_ID_PLT, plt->PlotRect); } bool BeginDragDropTargetX() { - return BeginDragDropTargetEx(IMPLOT_ID_XAX, GImPlot->CurrentPlot->XAxis.HoverRect); + ImPlotPlot* plt = GetCurrentOrPreviousPlot(); + if (plt == NULL) + return false; + return BeginDragDropTargetEx(IMPLOT_ID_XAX, plt->XAxis.HoverRect); } bool BeginDragDropTargetY(ImPlotYAxis axis) { - return BeginDragDropTargetEx(IMPLOT_ID_YAX + axis, GImPlot->CurrentPlot->YAxis[axis].HoverRect); + ImPlotPlot* plt = GetCurrentOrPreviousPlot(); + if (plt == NULL) + return false; + return BeginDragDropTargetEx(IMPLOT_ID_YAX + axis, plt->YAxis[axis].HoverRect); } bool BeginDragDropTargetLegend() { - return !ImHasFlag(GImPlot->CurrentPlot->Flags,ImPlotFlags_NoLegend) && - BeginDragDropTargetEx(IMPLOT_ID_LEG, GImPlot->CurrentPlot->LegendRect); + ImPlotPlot* plt = GetCurrentOrPreviousPlot(); + if (plt == NULL) + return false; + return !ImHasFlag(plt->Flags,ImPlotFlags_NoLegend) && BeginDragDropTargetEx(IMPLOT_ID_LEG, plt->LegendRect); } void EndDragDropTarget() { @@ -2994,37 +3010,47 @@ bool BeginDragDropSourceEx(ImGuiID source_id, bool is_hovered, ImGuiDragDropFlag } bool BeginDragDropSource(ImGuiKeyModFlags key_mods, ImGuiDragDropFlags flags) { + ImPlotPlot* plt = GetCurrentOrPreviousPlot(); + if (plt == NULL) + return false; if (ImGui::GetIO().KeyMods == key_mods) { - GImPlot->CurrentPlot->XAxis.Dragging = false; + plt->XAxis.Dragging = false; for (int i = 0; i < IMPLOT_Y_AXES; ++i) - GImPlot->CurrentPlot->YAxis[i].Dragging = false; + plt->YAxis[i].Dragging = false; } const ImGuiID ID = GImGui->CurrentWindow->GetID(IMPLOT_ID_PLT); - ImRect rect = GImPlot->CurrentPlot->PlotRect; - return ImGui::ItemAdd(rect, ID, &rect) && BeginDragDropSourceEx(ID, GImPlot->CurrentPlot->PlotHovered, flags, key_mods); + ImRect rect = plt->PlotRect; + return ImGui::ItemAdd(rect, ID, &rect) && BeginDragDropSourceEx(ID, plt->PlotHovered, flags, key_mods); } bool BeginDragDropSourceX(ImGuiKeyModFlags key_mods, ImGuiDragDropFlags flags) { + ImPlotPlot* plt = GetCurrentOrPreviousPlot(); + if (plt == NULL) + return false; if (ImGui::GetIO().KeyMods == key_mods) - GImPlot->CurrentPlot->XAxis.Dragging = false; + plt->XAxis.Dragging = false; const ImGuiID ID = GImGui->CurrentWindow->GetID(IMPLOT_ID_XAX); - ImRect rect = GImPlot->CurrentPlot->XAxis.HoverRect; - return ImGui::ItemAdd(rect, ID, &rect) && BeginDragDropSourceEx(ID, GImPlot->CurrentPlot->XAxis.ExtHovered, flags, key_mods); + ImRect rect = plt->XAxis.HoverRect; + return ImGui::ItemAdd(rect, ID, &rect) && BeginDragDropSourceEx(ID, plt->XAxis.ExtHovered, flags, key_mods); } bool BeginDragDropSourceY(ImPlotYAxis axis, ImGuiKeyModFlags key_mods, ImGuiDragDropFlags flags) { + ImPlotPlot* plt = GetCurrentOrPreviousPlot(); + if (plt == NULL) + return false; if (ImGui::GetIO().KeyMods == key_mods) - GImPlot->CurrentPlot->YAxis[axis].Dragging = false; + plt->YAxis[axis].Dragging = false; const ImGuiID ID = GImGui->CurrentWindow->GetID(IMPLOT_ID_YAX + axis); - ImRect rect = GImPlot->CurrentPlot->YAxis[axis].HoverRect; - return ImGui::ItemAdd(rect, ID, &rect) && BeginDragDropSourceEx(ID, GImPlot->CurrentPlot->YAxis[axis].ExtHovered, flags, key_mods); + ImRect rect = plt->YAxis[axis].HoverRect; + return ImGui::ItemAdd(rect, ID, &rect) && BeginDragDropSourceEx(ID, plt->YAxis[axis].ExtHovered, flags, key_mods); } bool BeginDragDropSourceItem(const char* label_id, ImGuiDragDropFlags flags) { - ImPlotContext& gp = *GImPlot; - IM_ASSERT_USER_ERROR(gp.CurrentPlot != NULL, "BeginDragDropSourceItem() needs to be called between BeginPlot() and EndPlot()!"); + ImPlotPlot* plt = GetCurrentOrPreviousPlot(); + if (plt == NULL) + return false; ImGuiID source_id = ImGui::GetID(label_id); - ImPlotItem* item = gp.CurrentPlot->Items.GetByKey(source_id); + ImPlotItem* item = plt->Items.GetByKey(source_id); bool is_hovered = item && item->LegendHovered; return BeginDragDropSourceEx(source_id, is_hovered, flags, ImGuiKeyModFlags_None); } diff --git a/implot_demo.cpp b/implot_demo.cpp index f645036..0bb32fd 100644 --- a/implot_demo.cpp +++ b/implot_demo.cpp @@ -1089,48 +1089,52 @@ void ShowDemoWindow(bool* p_open) { ImPlot::SetNextLineStyle(mixed); ImPlot::PlotLine("##dndxy", &dndx->Data[0].y, &dndy->Data[0].y, dndx->Data.size(), 0, 2 * sizeof(float)); } - // allow the x-axis to be a DND target - if (ImPlot::BeginDragDropTargetX()) { - if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("MY_DND")) { - int i = *(int*)payload->Data; dndx = &dnd[i]; - } - ImPlot::EndDragDropTarget(); - } - // allow the x-axis to be a DND source - if (dndx != NULL && ImPlot::BeginDragDropSourceX()) { - ImGui::SetDragDropPayload("MY_DND", &dndx->Idx, sizeof(int)); - ImPlot::ItemIcon(dndx->Color); ImGui::SameLine(); - ImGui::TextUnformatted(dndx->Label); - ImPlot::EndDragDropSource(); - } - // allow the y-axis to be a DND target - if (ImPlot::BeginDragDropTargetY()) { - if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("MY_DND")) { - int i = *(int*)payload->Data; dndy = &dnd[i]; - } - ImPlot::EndDragDropTarget(); - } - // allow the y-axis to be a DND source - if (dndy != NULL && ImPlot::BeginDragDropSourceY()) { - ImGui::SetDragDropPayload("MY_DND", &dndy->Idx, sizeof(int)); - ImPlot::ItemIcon(dndy->Color); ImGui::SameLine(); - ImGui::TextUnformatted(dndy->Label); - ImPlot::EndDragDropSource(); - } - // allow the plot area to be a DND target - if (ImPlot::BeginDragDropTarget()) { - if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("MY_DND")) { - int i = *(int*)payload->Data; dndx = dndy = &dnd[i]; - } - } - // allow the plot area to be a DND source - if (ImPlot::BeginDragDropSource()) { - ImGui::TextUnformatted("Yes, you can\ndrag this!"); - ImPlot::EndDragDropSource(); - } ImPlot::EndPlot(); } ImPlot::PopStyleColor(2); + + // you can also add DND after EndPlot: + + // allow the x-axis to be a DND target + if (ImPlot::BeginDragDropTargetX()) { + if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("MY_DND")) { + int i = *(int*)payload->Data; dndx = &dnd[i]; + } + ImPlot::EndDragDropTarget(); + } + // allow the x-axis to be a DND source + if (dndx != NULL && ImPlot::BeginDragDropSourceX()) { + ImGui::SetDragDropPayload("MY_DND", &dndx->Idx, sizeof(int)); + ImPlot::ItemIcon(dndx->Color); ImGui::SameLine(); + ImGui::TextUnformatted(dndx->Label); + ImPlot::EndDragDropSource(); + } + // allow the y-axis to be a DND target + if (ImPlot::BeginDragDropTargetY()) { + if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("MY_DND")) { + int i = *(int*)payload->Data; dndy = &dnd[i]; + } + ImPlot::EndDragDropTarget(); + } + // allow the y-axis to be a DND source + if (dndy != NULL && ImPlot::BeginDragDropSourceY()) { + ImGui::SetDragDropPayload("MY_DND", &dndy->Idx, sizeof(int)); + ImPlot::ItemIcon(dndy->Color); ImGui::SameLine(); + ImGui::TextUnformatted(dndy->Label); + ImPlot::EndDragDropSource(); + } + // allow the plot area to be a DND target + if (ImPlot::BeginDragDropTarget()) { + if (const ImGuiPayload* payload = ImGui::AcceptDragDropPayload("MY_DND")) { + int i = *(int*)payload->Data; dndx = dndy = &dnd[i]; + } + } + // allow the plot area to be a DND source + if (ImPlot::BeginDragDropSource()) { + ImGui::TextUnformatted("Yes, you can\ndrag this!"); + ImPlot::EndDragDropSource(); + } + ImGui::EndChild(); } //------------------------------------------------------------------------- diff --git a/implot_internal.h b/implot_internal.h index 136ad24..9abe5d7 100644 --- a/implot_internal.h +++ b/implot_internal.h @@ -658,11 +658,12 @@ struct ImPlotNextItemData { } }; -// Holds state information that must persist between calls to BeginPlot()/EndPlot() +// Holds transient state information that must persist between calls to BeginPlot()/EndPlot() struct ImPlotContext { // Plot States ImPool Plots; ImPlotPlot* CurrentPlot; + ImPlotPlot* PreviousPlot; ImPlotItem* CurrentItem; ImPlotItem* PreviousItem; @@ -748,6 +749,8 @@ IMPLOT_API ImPlotInputMap& GetInputMap(); IMPLOT_API ImPlotPlot* GetPlot(const char* title); // Gets the current plot from the current ImPlotContext IMPLOT_API ImPlotPlot* GetCurrentPlot(); +// Gets the current or previous plot from the current ImPlotContext +IMPLOT_API ImPlotPlot* GetCurrentOrPreviousPlot(); // Busts the cache for every plot in the current context IMPLOT_API void BustPlotCache();