1
0
Fork 0
mirror of https://github.com/gwm17/implot.git synced 2024-11-22 18:28:53 -05:00

Avoid fetching GImPlot multiple times when possible. (#468)

In the case this is a thread_local variable it is best to avoid fetching too many times.
Either way local caching tends to be beneficial as a non-local variable would often be fetched multiple times.
This commit is contained in:
omar 2023-04-19 18:35:30 +02:00 committed by GitHub
parent fb084f3719
commit 18758e237e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 141 additions and 107 deletions

View File

@ -532,8 +532,9 @@ ImPlotPlot* GetCurrentPlot() {
} }
void BustPlotCache() { void BustPlotCache() {
GImPlot->Plots.Clear(); ImPlotContext& gp = *GImPlot;
GImPlot->Subplots.Clear(); gp.Plots.Clear();
gp.Subplots.Clear();
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -596,7 +597,7 @@ bool ShowLegendEntries(ImPlotItemGroup& items, const ImRect& legend_bb, bool hov
const float icon_size = txt_ht; const float icon_size = txt_ht;
const float icon_shrink = 2; const float icon_shrink = 2;
ImU32 col_txt = GetStyleColorU32(ImPlotCol_LegendText); ImU32 col_txt = GetStyleColorU32(ImPlotCol_LegendText);
ImU32 col_txt_dis = ImAlphaU32(col_txt, 0.25f); ImU32 col_txt_dis = ImAlphaU32(col_txt, 0.25f);
// render each legend item // render each legend item
float sum_label_width = 0; float sum_label_width = 0;
bool any_item_hovered = false; bool any_item_hovered = false;
@ -605,12 +606,13 @@ bool ShowLegendEntries(ImPlotItemGroup& items, const ImRect& legend_bb, bool hov
if (num_items < 1) if (num_items < 1)
return hovered; return hovered;
// build render order // build render order
ImVector<int>& indices = GImPlot->TempInt1; ImPlotContext& gp = *GImPlot;
ImVector<int>& indices = gp.TempInt1;
indices.resize(num_items); indices.resize(num_items);
for (int i = 0; i < num_items; ++i) for (int i = 0; i < num_items; ++i)
indices[i] = i; indices[i] = i;
if (ImHasFlag(items.Legend.Flags, ImPlotLegendFlags_Sort) && num_items > 1) { if (ImHasFlag(items.Legend.Flags, ImPlotLegendFlags_Sort) && num_items > 1) {
GImPlot->SortItems = &items; gp.SortItems = &items;
qsort(indices.Data, num_items, sizeof(int), LegendSortingComp); qsort(indices.Data, num_items, sizeof(int), LegendSortingComp);
} }
// render // render
@ -995,19 +997,20 @@ ImPlotTime AddTime(const ImPlotTime& t, ImPlotTimeUnit unit, int count) {
} }
ImPlotTime FloorTime(const ImPlotTime& t, ImPlotTimeUnit unit) { ImPlotTime FloorTime(const ImPlotTime& t, ImPlotTimeUnit unit) {
GetTime(t, &GImPlot->Tm); ImPlotContext& gp = *GImPlot;
GetTime(t, &gp.Tm);
switch (unit) { switch (unit) {
case ImPlotTimeUnit_S: return ImPlotTime(t.S, 0); case ImPlotTimeUnit_S: return ImPlotTime(t.S, 0);
case ImPlotTimeUnit_Ms: return ImPlotTime(t.S, (t.Us / 1000) * 1000); case ImPlotTimeUnit_Ms: return ImPlotTime(t.S, (t.Us / 1000) * 1000);
case ImPlotTimeUnit_Us: return t; case ImPlotTimeUnit_Us: return t;
case ImPlotTimeUnit_Yr: GImPlot->Tm.tm_mon = 0; // fall-through case ImPlotTimeUnit_Yr: gp.Tm.tm_mon = 0; // fall-through
case ImPlotTimeUnit_Mo: GImPlot->Tm.tm_mday = 1; // fall-through case ImPlotTimeUnit_Mo: gp.Tm.tm_mday = 1; // fall-through
case ImPlotTimeUnit_Day: GImPlot->Tm.tm_hour = 0; // fall-through case ImPlotTimeUnit_Day: gp.Tm.tm_hour = 0; // fall-through
case ImPlotTimeUnit_Hr: GImPlot->Tm.tm_min = 0; // fall-through case ImPlotTimeUnit_Hr: gp.Tm.tm_min = 0; // fall-through
case ImPlotTimeUnit_Min: GImPlot->Tm.tm_sec = 0; break; case ImPlotTimeUnit_Min: gp.Tm.tm_sec = 0; break;
default: return t; default: return t;
} }
return MkTime(&GImPlot->Tm); return MkTime(&gp.Tm);
} }
ImPlotTime CeilTime(const ImPlotTime& t, ImPlotTimeUnit unit) { ImPlotTime CeilTime(const ImPlotTime& t, ImPlotTimeUnit unit) {
@ -1023,12 +1026,13 @@ ImPlotTime RoundTime(const ImPlotTime& t, ImPlotTimeUnit unit) {
} }
ImPlotTime CombineDateTime(const ImPlotTime& date_part, const ImPlotTime& tod_part) { ImPlotTime CombineDateTime(const ImPlotTime& date_part, const ImPlotTime& tod_part) {
tm& Tm = GImPlot->Tm; ImPlotContext& gp = *GImPlot;
GetTime(date_part, &GImPlot->Tm); tm& Tm = gp.Tm;
GetTime(date_part, &gp.Tm);
int y = Tm.tm_year; int y = Tm.tm_year;
int m = Tm.tm_mon; int m = Tm.tm_mon;
int d = Tm.tm_mday; int d = Tm.tm_mday;
GetTime(tod_part, &GImPlot->Tm); GetTime(tod_part, &gp.Tm);
Tm.tm_year = y; Tm.tm_year = y;
Tm.tm_mon = m; Tm.tm_mon = m;
Tm.tm_mday = d; Tm.tm_mday = d;
@ -1483,7 +1487,8 @@ void ShowSubplotsContextMenu(ImPlotSubplot& subplot) {
} }
void ShowPlotContextMenu(ImPlotPlot& plot) { void ShowPlotContextMenu(ImPlotPlot& plot) {
const bool owns_legend = GImPlot->CurrentItems == &plot.Items; ImPlotContext& gp = *GImPlot;
const bool owns_legend = gp.CurrentItems == &plot.Items;
const bool equal = ImHasFlag(plot.Flags, ImPlotFlags_Equal); const bool equal = ImHasFlag(plot.Flags, ImPlotFlags_Equal);
char buf[16] = {}; char buf[16] = {};
@ -1515,15 +1520,15 @@ void ShowPlotContextMenu(ImPlotPlot& plot) {
} }
ImGui::Separator(); ImGui::Separator();
if (!ImHasFlag(GImPlot->CurrentItems->Legend.Flags, ImPlotLegendFlags_NoMenus)) { if (!ImHasFlag(gp.CurrentItems->Legend.Flags, ImPlotLegendFlags_NoMenus)) {
if ((ImGui::BeginMenu("Legend"))) { if ((ImGui::BeginMenu("Legend"))) {
if (owns_legend) { if (owns_legend) {
if (ShowLegendContextMenu(plot.Items.Legend, !ImHasFlag(plot.Flags, ImPlotFlags_NoLegend))) if (ShowLegendContextMenu(plot.Items.Legend, !ImHasFlag(plot.Flags, ImPlotFlags_NoLegend)))
ImFlipFlag(plot.Flags, ImPlotFlags_NoLegend); ImFlipFlag(plot.Flags, ImPlotFlags_NoLegend);
} }
else if (GImPlot->CurrentSubplot != nullptr) { else if (gp.CurrentSubplot != nullptr) {
if (ShowLegendContextMenu(GImPlot->CurrentSubplot->Items.Legend, !ImHasFlag(GImPlot->CurrentSubplot->Flags, ImPlotSubplotFlags_NoLegend))) if (ShowLegendContextMenu(gp.CurrentSubplot->Items.Legend, !ImHasFlag(gp.CurrentSubplot->Flags, ImPlotSubplotFlags_NoLegend)))
ImFlipFlag(GImPlot->CurrentSubplot->Flags, ImPlotSubplotFlags_NoLegend); ImFlipFlag(gp.CurrentSubplot->Flags, ImPlotSubplotFlags_NoLegend);
} }
ImGui::EndMenu(); ImGui::EndMenu();
} }
@ -1543,10 +1548,10 @@ void ShowPlotContextMenu(ImPlotPlot& plot) {
ImFlipFlag(plot.Flags, ImPlotFlags_Crosshairs); ImFlipFlag(plot.Flags, ImPlotFlags_Crosshairs);
ImGui::EndMenu(); ImGui::EndMenu();
} }
if (GImPlot->CurrentSubplot != nullptr && !ImHasFlag(GImPlot->CurrentPlot->Flags, ImPlotSubplotFlags_NoMenus)) { if (gp.CurrentSubplot != nullptr && !ImHasFlag(gp.CurrentPlot->Flags, ImPlotSubplotFlags_NoMenus)) {
ImGui::Separator(); ImGui::Separator();
if ((ImGui::BeginMenu("Subplots"))) { if ((ImGui::BeginMenu("Subplots"))) {
ShowSubplotsContextMenu(*GImPlot->CurrentSubplot); ShowSubplotsContextMenu(*gp.CurrentSubplot);
ImGui::EndMenu(); ImGui::EndMenu();
} }
} }
@ -2057,7 +2062,7 @@ bool UpdateInput(ImPlotPlot& plot) {
void ApplyNextPlotData(ImAxis idx) { void ApplyNextPlotData(ImAxis idx) {
ImPlotContext& gp = *GImPlot; ImPlotContext& gp = *GImPlot;
ImPlotPlot& plot = *GImPlot->CurrentPlot; ImPlotPlot& plot = *gp.CurrentPlot;
ImPlotAxis& axis = plot.Axes[idx]; ImPlotAxis& axis = plot.Axes[idx];
if (!axis.Enabled) if (!axis.Enabled)
return; return;
@ -2082,10 +2087,11 @@ void ApplyNextPlotData(ImAxis idx) {
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void SetupAxis(ImAxis idx, const char* label, ImPlotAxisFlags flags) { void SetupAxis(ImAxis idx, const char* label, ImPlotAxisFlags flags) {
IM_ASSERT_USER_ERROR(GImPlot->CurrentPlot != nullptr && !GImPlot->CurrentPlot->SetupLocked, ImPlotContext& gp = *GImPlot;
IM_ASSERT_USER_ERROR(gp.CurrentPlot != nullptr && !gp.CurrentPlot->SetupLocked,
"Setup needs to be called after BeginPlot and before any setup locking functions (e.g. PlotX)!"); "Setup needs to be called after BeginPlot and before any setup locking functions (e.g. PlotX)!");
// get plot and axis // get plot and axis
ImPlotPlot& plot = *GImPlot->CurrentPlot; ImPlotPlot& plot = *gp.CurrentPlot;
ImPlotAxis& axis = plot.Axes[idx]; ImPlotAxis& axis = plot.Axes[idx];
// set ID // set ID
axis.ID = plot.ID + idx + 1; axis.ID = plot.ID + idx + 1;
@ -2102,9 +2108,10 @@ void SetupAxis(ImAxis idx, const char* label, ImPlotAxisFlags flags) {
} }
void SetupAxisLimits(ImAxis idx, double min_lim, double max_lim, ImPlotCond cond) { void SetupAxisLimits(ImAxis idx, double min_lim, double max_lim, ImPlotCond cond) {
IM_ASSERT_USER_ERROR(GImPlot->CurrentPlot != nullptr && !GImPlot->CurrentPlot->SetupLocked, ImPlotContext& gp = *GImPlot;
IM_ASSERT_USER_ERROR(gp.CurrentPlot != nullptr && !gp.CurrentPlot->SetupLocked,
"Setup needs to be called after BeginPlot and before any setup locking functions (e.g. PlotX)!"); // get plot and axis "Setup needs to be called after BeginPlot and before any setup locking functions (e.g. PlotX)!"); // get plot and axis
ImPlotPlot& plot = *GImPlot->CurrentPlot; ImPlotPlot& plot = *gp.CurrentPlot;
ImPlotAxis& axis = plot.Axes[idx]; ImPlotAxis& axis = plot.Axes[idx];
IM_ASSERT_USER_ERROR(axis.Enabled, "Axis is not enabled! Did you forget to call SetupAxis()?"); IM_ASSERT_USER_ERROR(axis.Enabled, "Axis is not enabled! Did you forget to call SetupAxis()?");
if (!plot.Initialized || cond == ImPlotCond_Always) if (!plot.Initialized || cond == ImPlotCond_Always)
@ -2114,9 +2121,10 @@ void SetupAxisLimits(ImAxis idx, double min_lim, double max_lim, ImPlotCond cond
} }
void SetupAxisFormat(ImAxis idx, const char* fmt) { void SetupAxisFormat(ImAxis idx, const char* fmt) {
IM_ASSERT_USER_ERROR(GImPlot->CurrentPlot != nullptr && !GImPlot->CurrentPlot->SetupLocked, ImPlotContext& gp = *GImPlot;
IM_ASSERT_USER_ERROR(gp.CurrentPlot != nullptr && !gp.CurrentPlot->SetupLocked,
"Setup needs to be called after BeginPlot and before any setup locking functions (e.g. PlotX)!"); "Setup needs to be called after BeginPlot and before any setup locking functions (e.g. PlotX)!");
ImPlotPlot& plot = *GImPlot->CurrentPlot; ImPlotPlot& plot = *gp.CurrentPlot;
ImPlotAxis& axis = plot.Axes[idx]; ImPlotAxis& axis = plot.Axes[idx];
IM_ASSERT_USER_ERROR(axis.Enabled, "Axis is not enabled! Did you forget to call SetupAxis()?"); IM_ASSERT_USER_ERROR(axis.Enabled, "Axis is not enabled! Did you forget to call SetupAxis()?");
axis.HasFormatSpec = fmt != nullptr; axis.HasFormatSpec = fmt != nullptr;
@ -2125,9 +2133,10 @@ void SetupAxisFormat(ImAxis idx, const char* fmt) {
} }
void SetupAxisLinks(ImAxis idx, double* min_lnk, double* max_lnk) { void SetupAxisLinks(ImAxis idx, double* min_lnk, double* max_lnk) {
IM_ASSERT_USER_ERROR(GImPlot->CurrentPlot != nullptr && !GImPlot->CurrentPlot->SetupLocked, ImPlotContext& gp = *GImPlot;
IM_ASSERT_USER_ERROR(gp.CurrentPlot != nullptr && !gp.CurrentPlot->SetupLocked,
"Setup needs to be called after BeginPlot and before any setup locking functions (e.g. PlotX)!"); "Setup needs to be called after BeginPlot and before any setup locking functions (e.g. PlotX)!");
ImPlotPlot& plot = *GImPlot->CurrentPlot; ImPlotPlot& plot = *gp.CurrentPlot;
ImPlotAxis& axis = plot.Axes[idx]; ImPlotAxis& axis = plot.Axes[idx];
IM_ASSERT_USER_ERROR(axis.Enabled, "Axis is not enabled! Did you forget to call SetupAxis()?"); IM_ASSERT_USER_ERROR(axis.Enabled, "Axis is not enabled! Did you forget to call SetupAxis()?");
axis.LinkedMin = min_lnk; axis.LinkedMin = min_lnk;
@ -2136,9 +2145,10 @@ void SetupAxisLinks(ImAxis idx, double* min_lnk, double* max_lnk) {
} }
void SetupAxisFormat(ImAxis idx, ImPlotFormatter formatter, void* data) { void SetupAxisFormat(ImAxis idx, ImPlotFormatter formatter, void* data) {
IM_ASSERT_USER_ERROR(GImPlot->CurrentPlot != nullptr && !GImPlot->CurrentPlot->SetupLocked, ImPlotContext& gp = *GImPlot;
IM_ASSERT_USER_ERROR(gp.CurrentPlot != nullptr && !gp.CurrentPlot->SetupLocked,
"Setup needs to be called after BeginPlot and before any setup locking functions (e.g. PlotX)!"); "Setup needs to be called after BeginPlot and before any setup locking functions (e.g. PlotX)!");
ImPlotPlot& plot = *GImPlot->CurrentPlot; ImPlotPlot& plot = *gp.CurrentPlot;
ImPlotAxis& axis = plot.Axes[idx]; ImPlotAxis& axis = plot.Axes[idx];
IM_ASSERT_USER_ERROR(axis.Enabled, "Axis is not enabled! Did you forget to call SetupAxis()?"); IM_ASSERT_USER_ERROR(axis.Enabled, "Axis is not enabled! Did you forget to call SetupAxis()?");
axis.Formatter = formatter; axis.Formatter = formatter;
@ -2146,9 +2156,10 @@ void SetupAxisFormat(ImAxis idx, ImPlotFormatter formatter, void* data) {
} }
void SetupAxisTicks(ImAxis idx, const double* values, int n_ticks, const char* const labels[], bool show_default) { void SetupAxisTicks(ImAxis idx, const double* values, int n_ticks, const char* const labels[], bool show_default) {
IM_ASSERT_USER_ERROR(GImPlot->CurrentPlot != nullptr && !GImPlot->CurrentPlot->SetupLocked, ImPlotContext& gp = *GImPlot;
IM_ASSERT_USER_ERROR(gp.CurrentPlot != nullptr && !gp.CurrentPlot->SetupLocked,
"Setup needs to be called after BeginPlot and before any setup locking functions (e.g. PlotX)!"); "Setup needs to be called after BeginPlot and before any setup locking functions (e.g. PlotX)!");
ImPlotPlot& plot = *GImPlot->CurrentPlot; ImPlotPlot& plot = *gp.CurrentPlot;
ImPlotAxis& axis = plot.Axes[idx]; ImPlotAxis& axis = plot.Axes[idx];
IM_ASSERT_USER_ERROR(axis.Enabled, "Axis is not enabled! Did you forget to call SetupAxis()?"); IM_ASSERT_USER_ERROR(axis.Enabled, "Axis is not enabled! Did you forget to call SetupAxis()?");
axis.ShowDefaultTicks = show_default; axis.ShowDefaultTicks = show_default;
@ -2161,17 +2172,19 @@ void SetupAxisTicks(ImAxis idx, const double* values, int n_ticks, const char* c
} }
void SetupAxisTicks(ImAxis idx, double v_min, double v_max, int n_ticks, const char* const labels[], bool show_default) { void SetupAxisTicks(ImAxis idx, double v_min, double v_max, int n_ticks, const char* const labels[], bool show_default) {
IM_ASSERT_USER_ERROR(GImPlot->CurrentPlot != nullptr && !GImPlot->CurrentPlot->SetupLocked, ImPlotContext& gp = *GImPlot;
IM_ASSERT_USER_ERROR(gp.CurrentPlot != nullptr && !gp.CurrentPlot->SetupLocked,
"Setup needs to be called after BeginPlot and before any setup locking functions (e.g. PlotX)!"); "Setup needs to be called after BeginPlot and before any setup locking functions (e.g. PlotX)!");
n_ticks = n_ticks < 2 ? 2 : n_ticks; n_ticks = n_ticks < 2 ? 2 : n_ticks;
FillRange(GImPlot->TempDouble1, n_ticks, v_min, v_max); FillRange(gp.TempDouble1, n_ticks, v_min, v_max);
SetupAxisTicks(idx, GImPlot->TempDouble1.Data, n_ticks, labels, show_default); SetupAxisTicks(idx, gp.TempDouble1.Data, n_ticks, labels, show_default);
} }
void SetupAxisScale(ImAxis idx, ImPlotScale scale) { void SetupAxisScale(ImAxis idx, ImPlotScale scale) {
IM_ASSERT_USER_ERROR(GImPlot->CurrentPlot != nullptr && !GImPlot->CurrentPlot->SetupLocked, ImPlotContext& gp = *GImPlot;
IM_ASSERT_USER_ERROR(gp.CurrentPlot != nullptr && !gp.CurrentPlot->SetupLocked,
"Setup needs to be called after BeginPlot and before any setup locking functions (e.g. PlotX)!"); "Setup needs to be called after BeginPlot and before any setup locking functions (e.g. PlotX)!");
ImPlotPlot& plot = *GImPlot->CurrentPlot; ImPlotPlot& plot = *gp.CurrentPlot;
ImPlotAxis& axis = plot.Axes[idx]; ImPlotAxis& axis = plot.Axes[idx];
IM_ASSERT_USER_ERROR(axis.Enabled, "Axis is not enabled! Did you forget to call SetupAxis()?"); IM_ASSERT_USER_ERROR(axis.Enabled, "Axis is not enabled! Did you forget to call SetupAxis()?");
axis.Scale = scale; axis.Scale = scale;
@ -2210,9 +2223,10 @@ void SetupAxisScale(ImAxis idx, ImPlotScale scale) {
} }
void SetupAxisScale(ImAxis idx, ImPlotTransform fwd, ImPlotTransform inv, void* data) { void SetupAxisScale(ImAxis idx, ImPlotTransform fwd, ImPlotTransform inv, void* data) {
IM_ASSERT_USER_ERROR(GImPlot->CurrentPlot != nullptr && !GImPlot->CurrentPlot->SetupLocked, ImPlotContext& gp = *GImPlot;
IM_ASSERT_USER_ERROR(gp.CurrentPlot != nullptr && !gp.CurrentPlot->SetupLocked,
"Setup needs to be called after BeginPlot and before any setup locking functions (e.g. PlotX)!"); "Setup needs to be called after BeginPlot and before any setup locking functions (e.g. PlotX)!");
ImPlotPlot& plot = *GImPlot->CurrentPlot; ImPlotPlot& plot = *gp.CurrentPlot;
ImPlotAxis& axis = plot.Axes[idx]; ImPlotAxis& axis = plot.Axes[idx];
IM_ASSERT_USER_ERROR(axis.Enabled, "Axis is not enabled! Did you forget to call SetupAxis()?"); IM_ASSERT_USER_ERROR(axis.Enabled, "Axis is not enabled! Did you forget to call SetupAxis()?");
axis.Scale = IMPLOT_AUTO; axis.Scale = IMPLOT_AUTO;
@ -2222,9 +2236,10 @@ void SetupAxisScale(ImAxis idx, ImPlotTransform fwd, ImPlotTransform inv, void*
} }
void SetupAxisLimitsConstraints(ImAxis idx, double v_min, double v_max) { void SetupAxisLimitsConstraints(ImAxis idx, double v_min, double v_max) {
IM_ASSERT_USER_ERROR(GImPlot->CurrentPlot != nullptr && !GImPlot->CurrentPlot->SetupLocked, ImPlotContext& gp = *GImPlot;
IM_ASSERT_USER_ERROR(gp.CurrentPlot != nullptr && !gp.CurrentPlot->SetupLocked,
"Setup needs to be called after BeginPlot and before any setup locking functions (e.g. PlotX)!"); "Setup needs to be called after BeginPlot and before any setup locking functions (e.g. PlotX)!");
ImPlotPlot& plot = *GImPlot->CurrentPlot; ImPlotPlot& plot = *gp.CurrentPlot;
ImPlotAxis& axis = plot.Axes[idx]; ImPlotAxis& axis = plot.Axes[idx];
IM_ASSERT_USER_ERROR(axis.Enabled, "Axis is not enabled! Did you forget to call SetupAxis()?"); IM_ASSERT_USER_ERROR(axis.Enabled, "Axis is not enabled! Did you forget to call SetupAxis()?");
axis.ConstraintRange.Min = v_min; axis.ConstraintRange.Min = v_min;
@ -2232,9 +2247,10 @@ void SetupAxisLimitsConstraints(ImAxis idx, double v_min, double v_max) {
} }
void SetupAxisZoomConstraints(ImAxis idx, double z_min, double z_max) { void SetupAxisZoomConstraints(ImAxis idx, double z_min, double z_max) {
IM_ASSERT_USER_ERROR(GImPlot->CurrentPlot != nullptr && !GImPlot->CurrentPlot->SetupLocked, ImPlotContext& gp = *GImPlot;
IM_ASSERT_USER_ERROR(gp.CurrentPlot != nullptr && !gp.CurrentPlot->SetupLocked,
"Setup needs to be called after BeginPlot and before any setup locking functions (e.g. PlotX)!"); "Setup needs to be called after BeginPlot and before any setup locking functions (e.g. PlotX)!");
ImPlotPlot& plot = *GImPlot->CurrentPlot; ImPlotPlot& plot = *gp.CurrentPlot;
ImPlotAxis& axis = plot.Axes[idx]; ImPlotAxis& axis = plot.Axes[idx];
IM_ASSERT_USER_ERROR(axis.Enabled, "Axis is not enabled! Did you forget to call SetupAxis()?"); IM_ASSERT_USER_ERROR(axis.Enabled, "Axis is not enabled! Did you forget to call SetupAxis()?");
axis.ConstraintZoom.Min = z_min; axis.ConstraintZoom.Min = z_min;
@ -2252,11 +2268,12 @@ void SetupAxesLimits(double x_min, double x_max, double y_min, double y_max, ImP
} }
void SetupLegend(ImPlotLocation location, ImPlotLegendFlags flags) { void SetupLegend(ImPlotLocation location, ImPlotLegendFlags flags) {
IM_ASSERT_USER_ERROR(GImPlot->CurrentPlot != nullptr && !GImPlot->CurrentPlot->SetupLocked, ImPlotContext& gp = *GImPlot;
IM_ASSERT_USER_ERROR(gp.CurrentPlot != nullptr && !gp.CurrentPlot->SetupLocked,
"Setup needs to be called after BeginPlot and before any setup locking functions (e.g. PlotX)!"); "Setup needs to be called after BeginPlot and before any setup locking functions (e.g. PlotX)!");
IM_ASSERT_USER_ERROR(GImPlot->CurrentItems != nullptr, IM_ASSERT_USER_ERROR(gp.CurrentItems != nullptr,
"SetupLegend() needs to be called within an itemized context!"); "SetupLegend() needs to be called within an itemized context!");
ImPlotLegend& legend = GImPlot->CurrentItems->Legend; ImPlotLegend& legend = gp.CurrentItems->Legend;
// check and set location // check and set location
if (location != legend.PreviousLocation) if (location != legend.PreviousLocation)
legend.Location = location; legend.Location = location;
@ -2268,10 +2285,11 @@ void SetupLegend(ImPlotLocation location, ImPlotLegendFlags flags) {
} }
void SetupMouseText(ImPlotLocation location, ImPlotMouseTextFlags flags) { void SetupMouseText(ImPlotLocation location, ImPlotMouseTextFlags flags) {
IM_ASSERT_USER_ERROR(GImPlot->CurrentPlot != nullptr && !GImPlot->CurrentPlot->SetupLocked, ImPlotContext& gp = *GImPlot;
IM_ASSERT_USER_ERROR(gp.CurrentPlot != nullptr && !gp.CurrentPlot->SetupLocked,
"Setup needs to be called after BeginPlot and before any setup locking functions (e.g. PlotX)!"); "Setup needs to be called after BeginPlot and before any setup locking functions (e.g. PlotX)!");
GImPlot->CurrentPlot->MouseTextLocation = location; gp.CurrentPlot->MouseTextLocation = location;
GImPlot->CurrentPlot->MouseTextFlags = flags; gp.CurrentPlot->MouseTextFlags = flags;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -2317,15 +2335,15 @@ void SetNextAxesToFit() {
bool BeginPlot(const char* title_id, const ImVec2& size, ImPlotFlags flags) { bool BeginPlot(const char* title_id, const ImVec2& size, ImPlotFlags flags) {
IM_ASSERT_USER_ERROR(GImPlot != nullptr, "No current context. Did you call ImPlot::CreateContext() or ImPlot::SetCurrentContext()?"); IM_ASSERT_USER_ERROR(GImPlot != nullptr, "No current context. Did you call ImPlot::CreateContext() or ImPlot::SetCurrentContext()?");
IM_ASSERT_USER_ERROR(GImPlot->CurrentPlot == nullptr, "Mismatched BeginPlot()/EndPlot()!"); ImPlotContext& gp = *GImPlot;
IM_ASSERT_USER_ERROR(gp.CurrentPlot == nullptr, "Mismatched BeginPlot()/EndPlot()!");
// FRONT MATTER ----------------------------------------------------------- // FRONT MATTER -----------------------------------------------------------
if (GImPlot->CurrentSubplot != nullptr) if (gp.CurrentSubplot != nullptr)
ImGui::PushID(GImPlot->CurrentSubplot->CurrentIdx); ImGui::PushID(gp.CurrentSubplot->CurrentIdx);
// get globals // get globals
ImPlotContext& gp = *GImPlot;
ImGuiContext &G = *GImGui; ImGuiContext &G = *GImGui;
ImGuiWindow* Window = G.CurrentWindow; ImGuiWindow* Window = G.CurrentWindow;
@ -2427,9 +2445,9 @@ bool BeginPlot(const char* title_id, const ImVec2& size, ImPlotFlags flags) {
void SetupFinish() { void SetupFinish() {
IM_ASSERT_USER_ERROR(GImPlot != nullptr, "No current context. Did you call ImPlot::CreateContext() or ImPlot::SetCurrentContext()?"); IM_ASSERT_USER_ERROR(GImPlot != nullptr, "No current context. Did you call ImPlot::CreateContext() or ImPlot::SetCurrentContext()?");
IM_ASSERT_USER_ERROR(GImPlot->CurrentPlot != nullptr, "SetupFinish needs to be called after BeginPlot!"); ImPlotContext& gp = *GImPlot;
IM_ASSERT_USER_ERROR(gp.CurrentPlot != nullptr, "SetupFinish needs to be called after BeginPlot!");
ImPlotContext& gp = *GImPlot;
ImGuiContext& G = *GImGui; ImGuiContext& G = *GImGui;
ImDrawList& DrawList = *G.CurrentWindow->DrawList; ImDrawList& DrawList = *G.CurrentWindow->DrawList;
const ImGuiStyle& Style = G.Style; const ImGuiStyle& Style = G.Style;
@ -2459,7 +2477,7 @@ void SetupFinish() {
} }
} }
// setup NULL orthogonal axes // setup nullptr orthogonal axes
const bool axis_equal = ImHasFlag(plot.Flags, ImPlotFlags_Equal); const bool axis_equal = ImHasFlag(plot.Flags, ImPlotFlags_Equal);
for (int ix = ImAxis_X1, iy = ImAxis_Y1; ix < ImAxis_Y1 || iy < ImAxis_COUNT; ++ix, ++iy) { for (int ix = ImAxis_X1, iy = ImAxis_Y1; ix < ImAxis_Y1 || iy < ImAxis_COUNT; ++ix, ++iy) {
ImPlotAxis& x_axis = plot.Axes[ix]; ImPlotAxis& x_axis = plot.Axes[ix];
@ -2727,11 +2745,11 @@ void SetupFinish() {
void EndPlot() { void EndPlot() {
IM_ASSERT_USER_ERROR(GImPlot != nullptr, "No current context. Did you call ImPlot::CreateContext() or ImPlot::SetCurrentContext()?"); IM_ASSERT_USER_ERROR(GImPlot != nullptr, "No current context. Did you call ImPlot::CreateContext() or ImPlot::SetCurrentContext()?");
IM_ASSERT_USER_ERROR(GImPlot->CurrentPlot != nullptr, "Mismatched BeginPlot()/EndPlot()!"); ImPlotContext& gp = *GImPlot;
IM_ASSERT_USER_ERROR(gp.CurrentPlot != nullptr, "Mismatched BeginPlot()/EndPlot()!");
SetupLock(); SetupLock();
ImPlotContext& gp = *GImPlot;
ImGuiContext &G = *GImGui; ImGuiContext &G = *GImGui;
ImPlotPlot &plot = *gp.CurrentPlot; ImPlotPlot &plot = *gp.CurrentPlot;
ImGuiWindow * Window = G.CurrentWindow; ImGuiWindow * Window = G.CurrentWindow;
@ -3266,8 +3284,8 @@ void SubplotNextCell() {
bool BeginSubplots(const char* title, int rows, int cols, const ImVec2& size, ImPlotSubplotFlags flags, float* row_sizes, float* col_sizes) { bool BeginSubplots(const char* title, int rows, int cols, const ImVec2& size, ImPlotSubplotFlags flags, float* row_sizes, float* col_sizes) {
IM_ASSERT_USER_ERROR(rows > 0 && cols > 0, "Invalid sizing arguments!"); IM_ASSERT_USER_ERROR(rows > 0 && cols > 0, "Invalid sizing arguments!");
IM_ASSERT_USER_ERROR(GImPlot != nullptr, "No current context. Did you call ImPlot::CreateContext() or ImPlot::SetCurrentContext()?"); IM_ASSERT_USER_ERROR(GImPlot != nullptr, "No current context. Did you call ImPlot::CreateContext() or ImPlot::SetCurrentContext()?");
IM_ASSERT_USER_ERROR(GImPlot->CurrentSubplot == nullptr, "Mismatched BeginSubplots()/EndSubplots()!");
ImPlotContext& gp = *GImPlot; ImPlotContext& gp = *GImPlot;
IM_ASSERT_USER_ERROR(gp.CurrentSubplot == nullptr, "Mismatched BeginSubplots()/EndSubplots()!");
ImGuiContext &G = *GImGui; ImGuiContext &G = *GImGui;
ImGuiWindow * Window = G.CurrentWindow; ImGuiWindow * Window = G.CurrentWindow;
if (Window->SkipItems) if (Window->SkipItems)
@ -3467,9 +3485,9 @@ bool BeginSubplots(const char* title, int rows, int cols, const ImVec2& size, Im
void EndSubplots() { void EndSubplots() {
IM_ASSERT_USER_ERROR(GImPlot != nullptr, "No current context. Did you call ImPlot::CreateContext() or ImPlot::SetCurrentContext()?"); IM_ASSERT_USER_ERROR(GImPlot != nullptr, "No current context. Did you call ImPlot::CreateContext() or ImPlot::SetCurrentContext()?");
IM_ASSERT_USER_ERROR(GImPlot->CurrentSubplot != nullptr, "Mismatched BeginSubplots()/EndSubplots()!");
ImPlotContext& gp = *GImPlot; ImPlotContext& gp = *GImPlot;
ImPlotSubplot& subplot = *GImPlot->CurrentSubplot; IM_ASSERT_USER_ERROR(gp.CurrentSubplot != nullptr, "Mismatched BeginSubplots()/EndSubplots()!");
ImPlotSubplot& subplot = *gp.CurrentSubplot;
// set alignments // set alignments
for (int r = 0; r < subplot.Rows; ++r) for (int r = 0; r < subplot.Rows; ++r)
subplot.RowAlignmentData[r].End(); subplot.RowAlignmentData[r].End();
@ -3743,39 +3761,45 @@ void Tag(ImAxis axis, double v, const ImVec4& color, bool round) {
} }
IMPLOT_API void TagX(double x, const ImVec4& color, bool round) { IMPLOT_API void TagX(double x, const ImVec4& color, bool round) {
IM_ASSERT_USER_ERROR(GImPlot->CurrentPlot != nullptr, "TagX() needs to be called between BeginPlot() and EndPlot()!"); ImPlotContext& gp = *GImPlot;
Tag(GImPlot->CurrentPlot->CurrentX, x, color, round); IM_ASSERT_USER_ERROR(gp.CurrentPlot != nullptr, "TagX() needs to be called between BeginPlot() and EndPlot()!");
Tag(gp.CurrentPlot->CurrentX, x, color, round);
} }
IMPLOT_API void TagX(double x, const ImVec4& color, const char* fmt, ...) { IMPLOT_API void TagX(double x, const ImVec4& color, const char* fmt, ...) {
IM_ASSERT_USER_ERROR(GImPlot->CurrentPlot != nullptr, "TagX() needs to be called between BeginPlot() and EndPlot()!"); ImPlotContext& gp = *GImPlot;
IM_ASSERT_USER_ERROR(gp.CurrentPlot != nullptr, "TagX() needs to be called between BeginPlot() and EndPlot()!");
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
TagV(GImPlot->CurrentPlot->CurrentX,x,color,fmt,args); TagV(gp.CurrentPlot->CurrentX,x,color,fmt,args);
va_end(args); va_end(args);
} }
IMPLOT_API void TagXV(double x, const ImVec4& color, const char* fmt, va_list args) { IMPLOT_API void TagXV(double x, const ImVec4& color, const char* fmt, va_list args) {
IM_ASSERT_USER_ERROR(GImPlot->CurrentPlot != nullptr, "TagX() needs to be called between BeginPlot() and EndPlot()!"); ImPlotContext& gp = *GImPlot;
TagV(GImPlot->CurrentPlot->CurrentX, x, color, fmt, args); IM_ASSERT_USER_ERROR(gp.CurrentPlot != nullptr, "TagX() needs to be called between BeginPlot() and EndPlot()!");
TagV(gp.CurrentPlot->CurrentX, x, color, fmt, args);
} }
IMPLOT_API void TagY(double y, const ImVec4& color, bool round) { IMPLOT_API void TagY(double y, const ImVec4& color, bool round) {
IM_ASSERT_USER_ERROR(GImPlot->CurrentPlot != nullptr, "TagY() needs to be called between BeginPlot() and EndPlot()!"); ImPlotContext& gp = *GImPlot;
Tag(GImPlot->CurrentPlot->CurrentY, y, color, round); IM_ASSERT_USER_ERROR(gp.CurrentPlot != nullptr, "TagY() needs to be called between BeginPlot() and EndPlot()!");
Tag(gp.CurrentPlot->CurrentY, y, color, round);
} }
IMPLOT_API void TagY(double y, const ImVec4& color, const char* fmt, ...) { IMPLOT_API void TagY(double y, const ImVec4& color, const char* fmt, ...) {
IM_ASSERT_USER_ERROR(GImPlot->CurrentPlot != nullptr, "TagY() needs to be called between BeginPlot() and EndPlot()!"); ImPlotContext& gp = *GImPlot;
IM_ASSERT_USER_ERROR(gp.CurrentPlot != nullptr, "TagY() needs to be called between BeginPlot() and EndPlot()!");
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
TagV(GImPlot->CurrentPlot->CurrentY,y,color,fmt,args); TagV(gp.CurrentPlot->CurrentY,y,color,fmt,args);
va_end(args); va_end(args);
} }
IMPLOT_API void TagYV(double y, const ImVec4& color, const char* fmt, va_list args) { IMPLOT_API void TagYV(double y, const ImVec4& color, const char* fmt, va_list args) {
IM_ASSERT_USER_ERROR(GImPlot->CurrentPlot != nullptr, "TagY() needs to be called between BeginPlot() and EndPlot()!"); ImPlotContext& gp = *GImPlot;
TagV(GImPlot->CurrentPlot->CurrentY, y, color, fmt, args); IM_ASSERT_USER_ERROR(gp.CurrentPlot != nullptr, "TagY() needs to be called between BeginPlot() and EndPlot()!");
TagV(gp.CurrentPlot->CurrentY, y, color, fmt, args);
} }
static const float DRAG_GRAB_HALF_SIZE = 4.0f; static const float DRAG_GRAB_HALF_SIZE = 4.0f;
@ -4130,8 +4154,9 @@ void ShowAltLegend(const char* title_id, bool vertical, const ImVec2 size, bool
bool BeginDragDropTargetPlot() { bool BeginDragDropTargetPlot() {
SetupLock(); SetupLock();
ImRect rect = GImPlot->CurrentPlot->PlotRect; ImPlotContext& gp = *GImPlot;
return ImGui::BeginDragDropTargetCustom(rect, GImPlot->CurrentPlot->ID); ImRect rect = gp.CurrentPlot->PlotRect;
return ImGui::BeginDragDropTargetCustom(rect, gp.CurrentPlot->ID);
} }
bool BeginDragDropTargetAxis(ImAxis axis) { bool BeginDragDropTargetAxis(ImAxis axis) {
@ -4157,16 +4182,18 @@ void EndDragDropTarget() {
bool BeginDragDropSourcePlot(ImGuiDragDropFlags flags) { bool BeginDragDropSourcePlot(ImGuiDragDropFlags flags) {
SetupLock(); SetupLock();
ImPlotPlot* plot = GImPlot->CurrentPlot; ImPlotContext& gp = *GImPlot;
if (GImGui->IO.KeyMods == GImPlot->InputMap.OverrideMod || GImGui->DragDropPayload.SourceId == plot->ID) ImPlotPlot* plot = gp.CurrentPlot;
if (GImGui->IO.KeyMods == gp.InputMap.OverrideMod || GImGui->DragDropPayload.SourceId == plot->ID)
return ImGui::ItemAdd(plot->PlotRect, plot->ID) && ImGui::BeginDragDropSource(flags); return ImGui::ItemAdd(plot->PlotRect, plot->ID) && ImGui::BeginDragDropSource(flags);
return false; return false;
} }
bool BeginDragDropSourceAxis(ImAxis idx, ImGuiDragDropFlags flags) { bool BeginDragDropSourceAxis(ImAxis idx, ImGuiDragDropFlags flags) {
SetupLock(); SetupLock();
ImPlotAxis& axis = GImPlot->CurrentPlot->Axes[idx]; ImPlotContext& gp = *GImPlot;
if (GImGui->IO.KeyMods == GImPlot->InputMap.OverrideMod || GImGui->DragDropPayload.SourceId == axis.ID) ImPlotAxis& axis = gp.CurrentPlot->Axes[idx];
if (GImGui->IO.KeyMods == gp.InputMap.OverrideMod || GImGui->DragDropPayload.SourceId == axis.ID)
return ImGui::ItemAdd(axis.HoverRect, axis.ID) && ImGui::BeginDragDropSource(flags); return ImGui::ItemAdd(axis.HoverRect, axis.ID) && ImGui::BeginDragDropSource(flags);
return false; return false;
} }
@ -4194,8 +4221,8 @@ void EndDragDropSource() {
bool BeginAlignedPlots(const char* group_id, bool vertical) { bool BeginAlignedPlots(const char* group_id, bool vertical) {
IM_ASSERT_USER_ERROR(GImPlot != nullptr, "No current context. Did you call ImPlot::CreateContext() or ImPlot::SetCurrentContext()?"); IM_ASSERT_USER_ERROR(GImPlot != nullptr, "No current context. Did you call ImPlot::CreateContext() or ImPlot::SetCurrentContext()?");
IM_ASSERT_USER_ERROR(GImPlot->CurrentAlignmentH == nullptr && GImPlot->CurrentAlignmentV == nullptr, "Mismatched BeginAlignedPlots()/EndAlignedPlots()!");
ImPlotContext& gp = *GImPlot; ImPlotContext& gp = *GImPlot;
IM_ASSERT_USER_ERROR(gp.CurrentAlignmentH == nullptr && gp.CurrentAlignmentV == nullptr, "Mismatched BeginAlignedPlots()/EndAlignedPlots()!");
ImGuiContext &G = *GImGui; ImGuiContext &G = *GImGui;
ImGuiWindow * Window = G.CurrentWindow; ImGuiWindow * Window = G.CurrentWindow;
if (Window->SkipItems) if (Window->SkipItems)
@ -4215,8 +4242,8 @@ bool BeginAlignedPlots(const char* group_id, bool vertical) {
void EndAlignedPlots() { void EndAlignedPlots() {
IM_ASSERT_USER_ERROR(GImPlot != nullptr, "No current context. Did you call ImPlot::CreateContext() or ImPlot::SetCurrentContext()?"); IM_ASSERT_USER_ERROR(GImPlot != nullptr, "No current context. Did you call ImPlot::CreateContext() or ImPlot::SetCurrentContext()?");
IM_ASSERT_USER_ERROR(GImPlot->CurrentAlignmentH != nullptr || GImPlot->CurrentAlignmentV != nullptr, "Mismatched BeginAlignedPlots()/EndAlignedPlots()!");
ImPlotContext& gp = *GImPlot; ImPlotContext& gp = *GImPlot;
IM_ASSERT_USER_ERROR(gp.CurrentAlignmentH != nullptr || gp.CurrentAlignmentV != nullptr, "Mismatched BeginAlignedPlots()/EndAlignedPlots()!");
ImPlotAlignmentData* alignment = gp.CurrentAlignmentH != nullptr ? gp.CurrentAlignmentH : (gp.CurrentAlignmentV != nullptr ? gp.CurrentAlignmentV : nullptr); ImPlotAlignmentData* alignment = gp.CurrentAlignmentH != nullptr ? gp.CurrentAlignmentH : (gp.CurrentAlignmentV != nullptr ? gp.CurrentAlignmentV : nullptr);
if (alignment) if (alignment)
alignment->End(); alignment->End();
@ -4538,7 +4565,7 @@ void ColormapScale(const char* label, double scale_min, double scale_max, const
const float tick_width = gp.CTicker.Ticks[i].Major ? gp.Style.MajorTickLen.y : gp.Style.MinorTickLen.y; const float tick_width = gp.CTicker.Ticks[i].Major ? gp.Style.MajorTickLen.y : gp.Style.MinorTickLen.y;
const float tick_thick = gp.CTicker.Ticks[i].Major ? gp.Style.MajorTickSize.y : gp.Style.MinorTickSize.y; const float tick_thick = gp.CTicker.Ticks[i].Major ? gp.Style.MajorTickSize.y : gp.Style.MinorTickSize.y;
const float tick_t = (float)((y_pos_plt - scale_min) / (scale_max - scale_min)); const float tick_t = (float)((y_pos_plt - scale_min) / (scale_max - scale_min));
const ImU32 tick_col = CalcTextColor(GImPlot->ColormapData.LerpTable(cmap,tick_t)); const ImU32 tick_col = CalcTextColor(gp.ColormapData.LerpTable(cmap,tick_t));
if (y_pos < bb_grad.Max.y - 2 && y_pos > bb_grad.Min.y + 2) { if (y_pos < bb_grad.Max.y - 2 && y_pos > bb_grad.Min.y + 2) {
DrawList.AddLine(opposite ? ImVec2(bb_grad.Min.x+1, y_pos) : ImVec2(bb_grad.Max.x-1, y_pos), DrawList.AddLine(opposite ? ImVec2(bb_grad.Min.x+1, y_pos) : ImVec2(bb_grad.Max.x-1, y_pos),
opposite ? ImVec2(bb_grad.Min.x + tick_width, y_pos) : ImVec2(bb_grad.Max.x - tick_width, y_pos), opposite ? ImVec2(bb_grad.Min.x + tick_width, y_pos) : ImVec2(bb_grad.Max.x - tick_width, y_pos),
@ -4569,16 +4596,16 @@ bool ColormapSlider(const char* label, float* t, ImVec4* out, const char* format
ImPlotContext& gp = *GImPlot; ImPlotContext& gp = *GImPlot;
cmap = cmap == IMPLOT_AUTO ? gp.Style.Colormap : cmap; cmap = cmap == IMPLOT_AUTO ? gp.Style.Colormap : cmap;
IM_ASSERT_USER_ERROR(cmap >= 0 && cmap < gp.ColormapData.Count, "Invalid colormap index!"); IM_ASSERT_USER_ERROR(cmap >= 0 && cmap < gp.ColormapData.Count, "Invalid colormap index!");
const ImU32* keys = GImPlot->ColormapData.GetKeys(cmap); const ImU32* keys = gp.ColormapData.GetKeys(cmap);
const int count = GImPlot->ColormapData.GetKeyCount(cmap); const int count = gp.ColormapData.GetKeyCount(cmap);
const bool qual = GImPlot->ColormapData.IsQual(cmap); const bool qual = gp.ColormapData.IsQual(cmap);
const ImVec2 pos = ImGui::GetCurrentWindow()->DC.CursorPos; const ImVec2 pos = ImGui::GetCurrentWindow()->DC.CursorPos;
const float w = ImGui::CalcItemWidth(); const float w = ImGui::CalcItemWidth();
const float h = ImGui::GetFrameHeight(); const float h = ImGui::GetFrameHeight();
const ImRect rect = ImRect(pos.x,pos.y,pos.x+w,pos.y+h); const ImRect rect = ImRect(pos.x,pos.y,pos.x+w,pos.y+h);
RenderColorBar(keys,count,*ImGui::GetWindowDrawList(),rect,false,false,!qual); RenderColorBar(keys,count,*ImGui::GetWindowDrawList(),rect,false,false,!qual);
const ImU32 grab = CalcTextColor(GImPlot->ColormapData.LerpTable(cmap,*t)); const ImU32 grab = CalcTextColor(gp.ColormapData.LerpTable(cmap,*t));
// const ImU32 text = CalcTextColor(GImPlot->ColormapData.LerpTable(cmap,0.5f)); // const ImU32 text = CalcTextColor(gp.ColormapData.LerpTable(cmap,0.5f));
ImGui::PushStyleColor(ImGuiCol_FrameBg,IM_COL32_BLACK_TRANS); ImGui::PushStyleColor(ImGuiCol_FrameBg,IM_COL32_BLACK_TRANS);
ImGui::PushStyleColor(ImGuiCol_FrameBgActive,IM_COL32_BLACK_TRANS); ImGui::PushStyleColor(ImGuiCol_FrameBgActive,IM_COL32_BLACK_TRANS);
ImGui::PushStyleColor(ImGuiCol_FrameBgHovered,ImVec4(1,1,1,0.1f)); ImGui::PushStyleColor(ImGuiCol_FrameBgHovered,ImVec4(1,1,1,0.1f));
@ -4590,7 +4617,7 @@ bool ColormapSlider(const char* label, float* t, ImVec4* out, const char* format
ImGui::PopStyleColor(5); ImGui::PopStyleColor(5);
ImGui::PopStyleVar(2); ImGui::PopStyleVar(2);
if (out != nullptr) if (out != nullptr)
*out = ImGui::ColorConvertU32ToFloat4(GImPlot->ColormapData.LerpTable(cmap,*t)); *out = ImGui::ColorConvertU32ToFloat4(gp.ColormapData.LerpTable(cmap,*t));
return changed; return changed;
} }
@ -4603,15 +4630,15 @@ bool ColormapButton(const char* label, const ImVec2& size_arg, ImPlotColormap cm
ImPlotContext& gp = *GImPlot; ImPlotContext& gp = *GImPlot;
cmap = cmap == IMPLOT_AUTO ? gp.Style.Colormap : cmap; cmap = cmap == IMPLOT_AUTO ? gp.Style.Colormap : cmap;
IM_ASSERT_USER_ERROR(cmap >= 0 && cmap < gp.ColormapData.Count, "Invalid colormap index!"); IM_ASSERT_USER_ERROR(cmap >= 0 && cmap < gp.ColormapData.Count, "Invalid colormap index!");
const ImU32* keys = GImPlot->ColormapData.GetKeys(cmap); const ImU32* keys = gp.ColormapData.GetKeys(cmap);
const int count = GImPlot->ColormapData.GetKeyCount(cmap); const int count = gp.ColormapData.GetKeyCount(cmap);
const bool qual = GImPlot->ColormapData.IsQual(cmap); const bool qual = gp.ColormapData.IsQual(cmap);
const ImVec2 pos = ImGui::GetCurrentWindow()->DC.CursorPos; const ImVec2 pos = ImGui::GetCurrentWindow()->DC.CursorPos;
const ImVec2 label_size = ImGui::CalcTextSize(label, nullptr, true); const ImVec2 label_size = ImGui::CalcTextSize(label, nullptr, true);
ImVec2 size = ImGui::CalcItemSize(size_arg, label_size.x + style.FramePadding.x * 2.0f, label_size.y + style.FramePadding.y * 2.0f); ImVec2 size = ImGui::CalcItemSize(size_arg, label_size.x + style.FramePadding.x * 2.0f, label_size.y + style.FramePadding.y * 2.0f);
const ImRect rect = ImRect(pos.x,pos.y,pos.x+size.x,pos.y+size.y); const ImRect rect = ImRect(pos.x,pos.y,pos.x+size.x,pos.y+size.y);
RenderColorBar(keys,count,*ImGui::GetWindowDrawList(),rect,false,false,!qual); RenderColorBar(keys,count,*ImGui::GetWindowDrawList(),rect,false,false,!qual);
const ImU32 text = CalcTextColor(GImPlot->ColormapData.LerpTable(cmap,G.Style.ButtonTextAlign.x)); const ImU32 text = CalcTextColor(gp.ColormapData.LerpTable(cmap,G.Style.ButtonTextAlign.x));
ImGui::PushStyleColor(ImGuiCol_Button,IM_COL32_BLACK_TRANS); ImGui::PushStyleColor(ImGuiCol_Button,IM_COL32_BLACK_TRANS);
ImGui::PushStyleColor(ImGuiCol_ButtonHovered,ImVec4(1,1,1,0.1f)); ImGui::PushStyleColor(ImGuiCol_ButtonHovered,ImVec4(1,1,1,0.1f));
ImGui::PushStyleColor(ImGuiCol_ButtonActive,ImVec4(1,1,1,0.2f)); ImGui::PushStyleColor(ImGuiCol_ButtonActive,ImVec4(1,1,1,0.2f));
@ -5486,8 +5513,9 @@ bool ShowDatePicker(const char* id, int* level, ImPlotTime* t, const ImPlotTime*
} }
bool ShowTimePicker(const char* id, ImPlotTime* t) { bool ShowTimePicker(const char* id, ImPlotTime* t) {
ImPlotContext& gp = *GImPlot;
ImGui::PushID(id); ImGui::PushID(id);
tm& Tm = GImPlot->Tm; tm& Tm = gp.Tm;
GetTime(*t,&Tm); GetTime(*t,&Tm);
static const char* nums[] = { "00","01","02","03","04","05","06","07","08","09", static const char* nums[] = { "00","01","02","03","04","05","06","07","08","09",
@ -5499,7 +5527,7 @@ bool ShowTimePicker(const char* id, ImPlotTime* t) {
static const char* am_pm[] = {"am","pm"}; static const char* am_pm[] = {"am","pm"};
bool hour24 = GImPlot->Style.Use24HourClock; bool hour24 = gp.Style.Use24HourClock;
int hr = hour24 ? Tm.tm_hour : ((Tm.tm_hour == 0 || Tm.tm_hour == 12) ? 12 : Tm.tm_hour % 12); int hr = hour24 ? Tm.tm_hour : ((Tm.tm_hour == 0 || Tm.tm_hour == 12) ? 12 : Tm.tm_hour % 12);
int min = Tm.tm_min; int min = Tm.tm_min;

View File

@ -1288,9 +1288,10 @@ IMPLOT_API void ShowPlotContextMenu(ImPlotPlot& plot);
// Lock Setup and call SetupFinish if necessary. // Lock Setup and call SetupFinish if necessary.
static inline void SetupLock() { static inline void SetupLock() {
if (!GImPlot->CurrentPlot->SetupLocked) ImPlotContext& gp = *GImPlot;
if (!gp.CurrentPlot->SetupLocked)
SetupFinish(); SetupFinish();
GImPlot->CurrentPlot->SetupLocked = true; gp.CurrentPlot->SetupLocked = true;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -1438,7 +1439,7 @@ static inline const ImPlotNextItemData& GetItemData() { return GImPlot->NextItem
// Returns true if a color is set to be automatically determined // Returns true if a color is set to be automatically determined
static inline bool IsColorAuto(const ImVec4& col) { return col.w == -1; } static inline bool IsColorAuto(const ImVec4& col) { return col.w == -1; }
// Returns true if a style color is set to be automaticaly determined // Returns true if a style color is set to be automatically determined
static inline bool IsColorAuto(ImPlotCol idx) { return IsColorAuto(GImPlot->Style.Colors[idx]); } static inline bool IsColorAuto(ImPlotCol idx) { return IsColorAuto(GImPlot->Style.Colors[idx]); }
// Returns the automatically deduced style color // Returns the automatically deduced style color
IMPLOT_API ImVec4 GetAutoColor(ImPlotCol idx); IMPLOT_API ImVec4 GetAutoColor(ImPlotCol idx);

View File

@ -1900,8 +1900,9 @@ void PlotBarGroups(const char* const label_ids[], const T* values, int item_coun
const bool stack = ImHasFlag(flags, ImPlotBarGroupsFlags_Stacked); const bool stack = ImHasFlag(flags, ImPlotBarGroupsFlags_Stacked);
if (stack) { if (stack) {
SetupLock(); SetupLock();
GImPlot->TempDouble1.resize(4*group_count); ImPlotContext& gp = *GImPlot;
double* temp = GImPlot->TempDouble1.Data; gp.TempDouble1.resize(4*group_count);
double* temp = gp.TempDouble1.Data;
double* neg = &temp[0]; double* neg = &temp[0];
double* pos = &temp[group_count]; double* pos = &temp[group_count];
double* curr_min = &temp[group_count*2]; double* curr_min = &temp[group_count*2];
@ -2254,7 +2255,8 @@ struct GetterHeatmapRowMaj {
rect.Pos = p; rect.Pos = p;
rect.HalfSize = HalfSize; rect.HalfSize = HalfSize;
const float t = ImClamp((float)ImRemap01(val, ScaleMin, ScaleMax),0.0f,1.0f); const float t = ImClamp((float)ImRemap01(val, ScaleMin, ScaleMax),0.0f,1.0f);
rect.Color = GImPlot->ColormapData.LerpTable(GImPlot->Style.Colormap, t); ImPlotContext& gp = *GImPlot;
rect.Color = gp.ColormapData.LerpTable(gp.Style.Colormap, t);
return rect; return rect;
} }
const T* const Values; const T* const Values;
@ -2288,7 +2290,8 @@ struct GetterHeatmapColMaj {
rect.Pos = p; rect.Pos = p;
rect.HalfSize = HalfSize; rect.HalfSize = HalfSize;
const float t = ImClamp((float)ImRemap01(val, ScaleMin, ScaleMax),0.0f,1.0f); const float t = ImClamp((float)ImRemap01(val, ScaleMin, ScaleMax),0.0f,1.0f);
rect.Color = GImPlot->ColormapData.LerpTable(GImPlot->Style.Colormap, t); ImPlotContext& gp = *GImPlot;
rect.Color = gp.ColormapData.LerpTable(gp.Style.Colormap, t);
return rect; return rect;
} }
const T* const Values; const T* const Values;
@ -2409,8 +2412,9 @@ double PlotHistogram(const char* label_id, const T* values, int count, int bins,
else else
width = range.Size() / bins; width = range.Size() / bins;
ImVector<double>& bin_centers = GImPlot->TempDouble1; ImPlotContext& gp = *GImPlot;
ImVector<double>& bin_counts = GImPlot->TempDouble2; ImVector<double>& bin_centers = gp.TempDouble1;
ImVector<double>& bin_counts = gp.TempDouble2;
bin_centers.resize(bins); bin_centers.resize(bins);
bin_counts.resize(bins); bin_counts.resize(bins);
int below = 0; int below = 0;
@ -2507,7 +2511,8 @@ double PlotHistogram2D(const char* label_id, const T* xs, const T* ys, int count
const int bins = x_bins * y_bins; const int bins = x_bins * y_bins;
ImVector<double>& bin_counts = GImPlot->TempDouble1; ImPlotContext& gp = *GImPlot;
ImVector<double>& bin_counts = gp.TempDouble1;
bin_counts.resize(bins); bin_counts.resize(bins);
for (int b = 0; b < bins; ++b) for (int b = 0; b < bins; ++b)