From 0182a86e0140085acfd52c064691e456d7860a66 Mon Sep 17 00:00:00 2001 From: ocornut Date: Tue, 4 Aug 2026 16:37:14 +0200 Subject: [PATCH 1/2] replace horizontal/vertical AddLine() calls to ImPlot's AddLineH() / AddLineV() wrappers. (#711) 3 remaining AddLine() calls to check evaluate for 1.93.0 change. --- implot.cpp | 56 ++++++++++++++++++++--------------------------- implot_demo.cpp | 4 +--- implot_internal.h | 9 ++++++++ implot_items.cpp | 10 ++++----- 4 files changed, 39 insertions(+), 40 deletions(-) diff --git a/implot.cpp b/implot.cpp index 00b09f06..c4485f40 100644 --- a/implot.cpp +++ b/implot.cpp @@ -1833,9 +1833,9 @@ static inline void RenderGridLinesX(ImDrawList& DrawList, const ImPlotTicker& ti continue; if (xt.Level == 0) { if (xt.Major) - DrawList.AddLine(ImVec2(xt.PixelPos, rect.Min.y), ImVec2(xt.PixelPos, rect.Max.y), col_maj, size_maj); + AddLineV(&DrawList, xt.PixelPos, rect.Min.y, rect.Max.y, col_maj, size_maj); else if (density < 0.2f) - DrawList.AddLine(ImVec2(xt.PixelPos, rect.Min.y), ImVec2(xt.PixelPos, rect.Max.y), col_min, size_min); + AddLineV(&DrawList, xt.PixelPos, rect.Min.y, rect.Max.y, col_min, size_min); } } } @@ -1850,9 +1850,9 @@ static inline void RenderGridLinesY(ImDrawList& DrawList, const ImPlotTicker& ti if (yt.PixelPos < rect.Min.y || yt.PixelPos > rect.Max.y) continue; if (yt.Major) - DrawList.AddLine(ImVec2(rect.Min.x, yt.PixelPos), ImVec2(rect.Max.x, yt.PixelPos), col_maj, size_maj); + AddLineH(&DrawList, rect.Min.x, rect.Max.x, yt.PixelPos, col_maj, size_maj); else if (density < 0.2f) - DrawList.AddLine(ImVec2(rect.Min.x, yt.PixelPos), ImVec2(rect.Max.x, yt.PixelPos), col_min, size_min); + AddLineH(&DrawList, rect.Min.x, rect.Max.x, yt.PixelPos, col_min, size_min); } } @@ -2885,10 +2885,10 @@ void EndPlot() { const ImVec2 start(tk.PixelPos, ax.Datum1); const float len = (!aux && tk.Major) ? gp.Style.MajorTickLen.x : gp.Style.MinorTickLen.x; const float thk = (!aux && tk.Major) ? gp.Style.MajorTickSize.x : gp.Style.MinorTickSize.x; - DrawList.AddLine(start, start + ImVec2(0,direction*len), ax.ColorTick, thk); + AddLineV(&DrawList, start.x, start.y, start.y + direction*len, ax.ColorTick, thk); } if (aux || !render_border) - DrawList.AddLine(ImVec2(plot.PlotRect.Min.x,ax.Datum1), ImVec2(plot.PlotRect.Max.x,ax.Datum1), ax.ColorTick, gp.Style.MinorTickSize.x); + AddLineH(&DrawList, plot.PlotRect.Min.x,plot.PlotRect.Max.x,ax.Datum1, ax.ColorTick, gp.Style.MinorTickSize.x); } count_B += !opp; count_T += opp; @@ -2912,10 +2912,10 @@ void EndPlot() { const ImVec2 start(ax.Datum1, tk.PixelPos); const float len = (!aux && tk.Major) ? gp.Style.MajorTickLen.y : gp.Style.MinorTickLen.y; const float thk = (!aux && tk.Major) ? gp.Style.MajorTickSize.y : gp.Style.MinorTickSize.y; - DrawList.AddLine(start, start + ImVec2(direction*len,0), ax.ColorTick, thk); + AddLineH(&DrawList, start.x, start.x + direction*len, start.y, ax.ColorTick, thk); } if (aux || !render_border) - DrawList.AddLine(ImVec2(ax.Datum1, plot.PlotRect.Min.y), ImVec2(ax.Datum1, plot.PlotRect.Max.y), ax.ColorTick, gp.Style.MinorTickSize.y); + AddLineV(&DrawList, ax.Datum1, plot.PlotRect.Min.y, plot.PlotRect.Max.y, ax.ColorTick, gp.Style.MinorTickSize.y); } count_L += !opp; count_R += opp; @@ -2970,19 +2970,11 @@ void EndPlot() { if (ImHasFlag(plot.Flags, ImPlotFlags_Crosshairs) && plot.Hovered && !(any_x_held || any_y_held) && !plot.Selecting && !plot.Items.Legend.Hovered) { ImGui::SetMouseCursor(ImGuiMouseCursor_None); ImVec2 xy = IO.MousePos; - ImVec2 h1(plot.PlotRect.Min.x, xy.y); - ImVec2 h2(xy.x - 5, xy.y); - ImVec2 h3(xy.x + 5, xy.y); - ImVec2 h4(plot.PlotRect.Max.x, xy.y); - ImVec2 v1(xy.x, plot.PlotRect.Min.y); - ImVec2 v2(xy.x, xy.y - 5); - ImVec2 v3(xy.x, xy.y + 5); - ImVec2 v4(xy.x, plot.PlotRect.Max.y); ImU32 col = GetStyleColorU32(ImPlotCol_Crosshairs); - DrawList.AddLine(h1, h2, col); - DrawList.AddLine(h3, h4, col); - DrawList.AddLine(v1, v2, col); - DrawList.AddLine(v3, v4, col); + AddLineH(&DrawList, plot.PlotRect.Min.x, xy.x - 5, xy.y, col); + AddLineH(&DrawList, xy.x + 5, plot.PlotRect.Max.x, xy.y, col); + AddLineV(&DrawList, xy.x, plot.PlotRect.Min.y, xy.y - 5, col); + AddLineV(&DrawList, xy.x, xy.y + 5, plot.PlotRect.Max.y, col); } // render mouse pos @@ -3540,8 +3532,7 @@ bool BeginSubplots(const char* title, int rows, int cols, const ImVec2& size, Im subplot.RowRatios[r+1] = subplot.TempSizes[1] - dp; } } - DrawList.AddLine(ImVec2(IM_ROUND(subplot.GridRect.Min.x),IM_ROUND(ypos)), - ImVec2(IM_ROUND(subplot.GridRect.Max.x),IM_ROUND(ypos)), + AddLineH(&DrawList, IM_ROUND(subplot.GridRect.Min.x), IM_ROUND(subplot.GridRect.Max.x),IM_ROUND(ypos), sep_hld ? act_col : hov_col, SUBPLOT_BORDER_SIZE); ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeNS); } @@ -3570,8 +3561,7 @@ bool BeginSubplots(const char* title, int rows, int cols, const ImVec2& size, Im subplot.ColRatios[c+1] = subplot.TempSizes[1] - dp; } } - DrawList.AddLine(ImVec2(IM_ROUND(xpos),IM_ROUND(subplot.GridRect.Min.y)), - ImVec2(IM_ROUND(xpos),IM_ROUND(subplot.GridRect.Max.y)), + AddLineV(&DrawList, IM_ROUND(xpos),IM_ROUND(subplot.GridRect.Min.y),IM_ROUND(subplot.GridRect.Max.y), sep_hld ? act_col : hov_col, SUBPLOT_BORDER_SIZE); ImGui::SetMouseCursor(ImGuiMouseCursor_ResizeEW); } @@ -4066,9 +4056,9 @@ bool DragLineX(int n_id, double* value, const ImVec4& col, float thickness, ImPl ImDrawList& DrawList = *GetPlotDrawList(); if (modified && no_delay) x = IM_ROUND(PlotToPixels(*value,0,IMPLOT_AUTO,IMPLOT_AUTO).x); - DrawList.AddLine(ImVec2(x,yt), ImVec2(x,yb), col32, thickness); - DrawList.AddLine(ImVec2(x,yt), ImVec2(x,yt+len), col32, 3*thickness); - DrawList.AddLine(ImVec2(x,yb), ImVec2(x,yb-len), col32, 3*thickness); + AddLineV(&DrawList,x,yt,yb, col32, thickness); + AddLineV(&DrawList,x,yt,yt+len, col32, 3*thickness); + AddLineV(&DrawList,x,yb,yb-len, col32, 3*thickness); PopPlotClipRect(); // ImGui::PopID(); @@ -4122,9 +4112,9 @@ bool DragLineY(int n_id, double* value, const ImVec4& col, float thickness, ImPl ImDrawList& DrawList = *GetPlotDrawList(); if (modified && no_delay) y = IM_ROUND(PlotToPixels(0, *value,IMPLOT_AUTO,IMPLOT_AUTO).y); - DrawList.AddLine(ImVec2(xl,y), ImVec2(xr,y), col32, thickness); - DrawList.AddLine(ImVec2(xl,y), ImVec2(xl+len,y), col32, 3*thickness); - DrawList.AddLine(ImVec2(xr,y), ImVec2(xr-len,y), col32, 3*thickness); + AddLineH(&DrawList,xl,xr,y, col32, thickness); + AddLineH(&DrawList,xl,xl+len,y, col32, 3*thickness); + AddLineH(&DrawList,xr,xr-len,y, col32, 3*thickness); PopPlotClipRect(); ImGui::PopID(); @@ -4778,8 +4768,10 @@ void ColormapScale(const char* label, double scale_min, double scale_max, const const float tick_t = (float)((y_pos_plt - scale_min) / (scale_max - scale_min)); 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) { - 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), + AddLineH(&DrawList, + opposite ? (bb_grad.Min.x+1) : (bb_grad.Max.x-1), + opposite ? (bb_grad.Min.x + tick_width) : (bb_grad.Max.x - tick_width), + y_pos, tick_col, tick_thick); } diff --git a/implot_demo.cpp b/implot_demo.cpp index 97b06567..1b92b618 100644 --- a/implot_demo.cpp +++ b/implot_demo.cpp @@ -3043,10 +3043,8 @@ void PlotCandlestick(const char* label_id, const double* xs, const double* opens for (int i = 0; i < count; ++i) { ImVec2 open_pos = ImPlot::PlotToPixels(xs[i] - half_width, opens[i]); ImVec2 close_pos = ImPlot::PlotToPixels(xs[i] + half_width, closes[i]); - ImVec2 low_pos = ImPlot::PlotToPixels(xs[i], lows[i]); - ImVec2 high_pos = ImPlot::PlotToPixels(xs[i], highs[i]); ImU32 color = ImGui::GetColorU32(opens[i] > closes[i] ? bearCol : bullCol); - draw_list->AddLine(low_pos, high_pos, color); + ImPlot::AddLineV(draw_list, (float)xs[i], (float)lows[i], (float)highs[i], color); draw_list->AddRectFilled(open_pos, close_pos, color); } diff --git a/implot_internal.h b/implot_internal.h index e7783270..bb1b9ab6 100644 --- a/implot_internal.h +++ b/implot_internal.h @@ -1508,6 +1508,15 @@ IMPLOT_API ImU32 SampleColormapU32(float t, ImPlotColormap cmap); // Render a colormap bar IMPLOT_API void RenderColorBar(const ImU32* colors, int size, ImDrawList& DrawList, const ImRect& bounds, bool vert, bool reversed, bool continuous); +// Render Horizontal/Vertical lines +#if (IMGUI_VERSION_NUM < 19275) +static inline void AddLineH(ImDrawList *draw_list, float x1, float x2, float y, ImU32 col, float thickness = 1.0f) { draw_list->AddLine(ImVec2(x1, y), ImVec2(x2, y), col, thickness); } +static inline void AddLineV(ImDrawList* draw_list, float x, float y1, float y2, ImU32 col, float thickness = 1.0f) { draw_list->AddLine(ImVec2(x, y1), ImVec2(x, y2), col, thickness); } +#else +static inline void AddLineH(ImDrawList *draw_list, float x1, float x2, float y, ImU32 col, float thickness = 1.0f) { draw_list->AddLineH(x1, x2, y, col, thickness); } +static inline void AddLineV(ImDrawList *draw_list, float x, float y1, float y2, ImU32 col, float thickness = 1.0f) { draw_list->AddLineV(x, y1, y2, col, thickness); } +#endif + //----------------------------------------------------------------------------- // [SECTION] Math and Misc Utils //----------------------------------------------------------------------------- diff --git a/implot_items.cpp b/implot_items.cpp index 807df125..4f7cea8b 100644 --- a/implot_items.cpp +++ b/implot_items.cpp @@ -2561,10 +2561,10 @@ void PlotErrorBarsVEx(const char* label_id, const _GetterPos& getter_pos, const for (int i = 0; i < getter_pos.Count; ++i) { ImVec2 p1 = PlotToPixels(getter_neg[i],IMPLOT_AUTO,IMPLOT_AUTO); ImVec2 p2 = PlotToPixels(getter_pos[i],IMPLOT_AUTO,IMPLOT_AUTO); - draw_list.AddLine(p1,p2,col, s.Spec.LineWeight); + draw_list.AddLine(p1, p2, col, s.Spec.LineWeight); if (rend_whisker) { - draw_list.AddLine(p1 - ImVec2(half_whisker, 0), p1 + ImVec2(half_whisker, 0), col, s.Spec.LineWeight); - draw_list.AddLine(p2 - ImVec2(half_whisker, 0), p2 + ImVec2(half_whisker, 0), col, s.Spec.LineWeight); + AddLineH(&draw_list, p1.x - half_whisker, p1.x + half_whisker, p1.y, col, s.Spec.LineWeight); + AddLineH(&draw_list, p2.x - half_whisker, p2.x + half_whisker, p2.y, col, s.Spec.LineWeight); } } EndItem(); @@ -2588,8 +2588,8 @@ void PlotErrorBarsHEx(const char* label_id, const _GetterPos& getter_pos, const ImVec2 p2 = PlotToPixels(getter_pos[i],IMPLOT_AUTO,IMPLOT_AUTO); draw_list.AddLine(p1, p2, col, s.Spec.LineWeight); if (rend_whisker) { - draw_list.AddLine(p1 - ImVec2(0, half_whisker), p1 + ImVec2(0, half_whisker), col, s.Spec.LineWeight); - draw_list.AddLine(p2 - ImVec2(0, half_whisker), p2 + ImVec2(0, half_whisker), col, s.Spec.LineWeight); + AddLineV(&draw_list, p1.x, p1.y - half_whisker, p1.y + half_whisker, col, s.Spec.LineWeight); + AddLineV(&draw_list, p2.x, p2.y - half_whisker, p2.y + half_whisker, col, s.Spec.LineWeight); } } EndItem(); From 6f59480cdd70bc73196ed57545ba701fa23010fc Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 8 Jun 2026 12:46:03 +0200 Subject: [PATCH 2/2] fix: use ImDrawList::_SelectLineTexture() --- implot_items.cpp | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/implot_items.cpp b/implot_items.cpp index 4f7cea8b..1c1fa709 100644 --- a/implot_items.cpp +++ b/implot_items.cpp @@ -157,7 +157,14 @@ static inline double ImStdDev(const TContainer& values, int count) { return sqrt(x); } -IMPLOT_INLINE void GetLineRenderProps(const ImDrawList& draw_list, float& half_weight, ImVec2& tex_uv0, ImVec2& tex_uv1) { +IMPLOT_INLINE void GetLineRenderProps(ImDrawList& draw_list, float& half_weight, ImVec2& tex_uv0, ImVec2& tex_uv1) { +#if IMGUI_VERSION_NUM >= 19299 || defined(IM_DRAWLIST_TEX_LINES_SAMPLE_COUNT) + float fringe; + draw_list._SelectLineTexture(half_weight * 2.0f, &tex_uv0, &tex_uv1, &fringe, draw_list.Flags); + //tex_uv0.x -= 0.5f * draw_list._Data->FontAtlas->TexUvScale.x; // Changed in features/drawlist_v193 but seems unncessary? + //tex_uv1.x -= 0.5f * draw_list._Data->FontAtlas->TexUvScale.x; + half_weight += fringe * 0.5f; +#else const bool aa = ImHasFlag(draw_list.Flags, ImDrawListFlags_AntiAliasedLines) && ImHasFlag(draw_list.Flags, ImDrawListFlags_AntiAliasedLinesUseTex); if (aa) { @@ -169,6 +176,7 @@ IMPLOT_INLINE void GetLineRenderProps(const ImDrawList& draw_list, float& half_w else { tex_uv0 = tex_uv1 = draw_list._Data->TexUvWhitePixel; } +#endif } IMPLOT_INLINE void PrimLine(ImDrawList& draw_list, const ImVec2& P1, const ImVec2& P2, float half_weight, ImU32 col, const ImVec2& tex_uv0, const ImVec2 tex_uv1) {