From 1f9b827badb2de4c4eaae11c0d02242ec90af7f6 Mon Sep 17 00:00:00 2001 From: Nic Gaffney Date: Mon, 13 Oct 2025 01:19:27 -0500 Subject: Updating to zig 0.15.1 --- vendor/zgui/libs/imgui/implot_items.cpp | 2808 ------------------------------- 1 file changed, 2808 deletions(-) delete mode 100644 vendor/zgui/libs/imgui/implot_items.cpp (limited to 'vendor/zgui/libs/imgui/implot_items.cpp') diff --git a/vendor/zgui/libs/imgui/implot_items.cpp b/vendor/zgui/libs/imgui/implot_items.cpp deleted file mode 100644 index 1871d15..0000000 --- a/vendor/zgui/libs/imgui/implot_items.cpp +++ /dev/null @@ -1,2808 +0,0 @@ -// MIT License - -// Copyright (c) 2023 Evan Pezent - -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: - -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. - -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -// ImPlot v0.17 - -#define IMGUI_DEFINE_MATH_OPERATORS -#include "implot.h" -#include "implot_internal.h" - -//----------------------------------------------------------------------------- -// [SECTION] Macros and Defines -//----------------------------------------------------------------------------- - -#define SQRT_1_2 0.70710678118f -#define SQRT_3_2 0.86602540378f - -#ifndef IMPLOT_NO_FORCE_INLINE - #ifdef _MSC_VER - #define IMPLOT_INLINE __forceinline - #elif defined(__GNUC__) - #define IMPLOT_INLINE inline __attribute__((__always_inline__)) - #elif defined(__CLANG__) - #if __has_attribute(__always_inline__) - #define IMPLOT_INLINE inline __attribute__((__always_inline__)) - #else - #define IMPLOT_INLINE inline - #endif - #else - #define IMPLOT_INLINE inline - #endif -#else - #define IMPLOT_INLINE inline -#endif - -#if defined __SSE__ || defined __x86_64__ || defined _M_X64 -#ifndef IMGUI_ENABLE_SSE -#include -#endif -static IMPLOT_INLINE float ImInvSqrt(float x) { return _mm_cvtss_f32(_mm_rsqrt_ss(_mm_set_ss(x))); } -#else -static IMPLOT_INLINE float ImInvSqrt(float x) { return 1.0f / sqrtf(x); } -#endif - -#define IMPLOT_NORMALIZE2F_OVER_ZERO(VX,VY) do { float d2 = VX*VX + VY*VY; if (d2 > 0.0f) { float inv_len = ImInvSqrt(d2); VX *= inv_len; VY *= inv_len; } } while (0) - -// Support for pre-1.82 versions. Users on 1.82+ can use 0 (default) flags to mean "all corners" but in order to support older versions we are more explicit. -#if (IMGUI_VERSION_NUM < 18102) && !defined(ImDrawFlags_RoundCornersAll) -#define ImDrawFlags_RoundCornersAll ImDrawCornerFlags_All -#endif - -//----------------------------------------------------------------------------- -// [SECTION] Template instantiation utility -//----------------------------------------------------------------------------- - -// By default, templates are instantiated for `float`, `double`, and for the following integer types, which are defined in imgui.h: -// signed char ImS8; // 8-bit signed integer -// unsigned char ImU8; // 8-bit unsigned integer -// signed short ImS16; // 16-bit signed integer -// unsigned short ImU16; // 16-bit unsigned integer -// signed int ImS32; // 32-bit signed integer == int -// unsigned int ImU32; // 32-bit unsigned integer -// signed long long ImS64; // 64-bit signed integer -// unsigned long long ImU64; // 64-bit unsigned integer -// (note: this list does *not* include `long`, `unsigned long` and `long double`) -// -// You can customize the supported types by defining IMPLOT_CUSTOM_NUMERIC_TYPES at compile time to define your own type list. -// As an example, you could use the compile time define given by the line below in order to support only float and double. -// -DIMPLOT_CUSTOM_NUMERIC_TYPES="(float)(double)" -// In order to support all known C++ types, use: -// -DIMPLOT_CUSTOM_NUMERIC_TYPES="(signed char)(unsigned char)(signed short)(unsigned short)(signed int)(unsigned int)(signed long)(unsigned long)(signed long long)(unsigned long long)(float)(double)(long double)" - -#ifdef IMPLOT_CUSTOM_NUMERIC_TYPES - #define IMPLOT_NUMERIC_TYPES IMPLOT_CUSTOM_NUMERIC_TYPES -#else - #define IMPLOT_NUMERIC_TYPES (ImS8)(ImU8)(ImS16)(ImU16)(ImS32)(ImU32)(ImS64)(ImU64)(float)(double) -#endif - -// CALL_INSTANTIATE_FOR_NUMERIC_TYPES will duplicate the template instantion code `INSTANTIATE_MACRO(T)` on supported types. -#define _CAT(x, y) _CAT_(x, y) -#define _CAT_(x,y) x ## y -#define _INSTANTIATE_FOR_NUMERIC_TYPES(chain) _CAT(_INSTANTIATE_FOR_NUMERIC_TYPES_1 chain, _END) -#define _INSTANTIATE_FOR_NUMERIC_TYPES_1(T) INSTANTIATE_MACRO(T) _INSTANTIATE_FOR_NUMERIC_TYPES_2 -#define _INSTANTIATE_FOR_NUMERIC_TYPES_2(T) INSTANTIATE_MACRO(T) _INSTANTIATE_FOR_NUMERIC_TYPES_1 -#define _INSTANTIATE_FOR_NUMERIC_TYPES_1_END -#define _INSTANTIATE_FOR_NUMERIC_TYPES_2_END -#define CALL_INSTANTIATE_FOR_NUMERIC_TYPES() _INSTANTIATE_FOR_NUMERIC_TYPES(IMPLOT_NUMERIC_TYPES) - -namespace ImPlot { - -//----------------------------------------------------------------------------- -// [SECTION] Utils -//----------------------------------------------------------------------------- - -// Calc maximum index size of ImDrawIdx -template -struct MaxIdx { static const unsigned int Value; }; -template <> const unsigned int MaxIdx::Value = 65535; -template <> const unsigned int MaxIdx::Value = 4294967295; - -IMPLOT_INLINE void GetLineRenderProps(const ImDrawList& draw_list, float& half_weight, ImVec2& tex_uv0, ImVec2& tex_uv1) { - const bool aa = ImHasFlag(draw_list.Flags, ImDrawListFlags_AntiAliasedLines) && - ImHasFlag(draw_list.Flags, ImDrawListFlags_AntiAliasedLinesUseTex); - if (aa) { - ImVec4 tex_uvs = draw_list._Data->TexUvLines[(int)(half_weight*2)]; - tex_uv0 = ImVec2(tex_uvs.x, tex_uvs.y); - tex_uv1 = ImVec2(tex_uvs.z, tex_uvs.w); - half_weight += 1; - } - else { - tex_uv0 = tex_uv1 = draw_list._Data->TexUvWhitePixel; - } -} - -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) { - float dx = P2.x - P1.x; - float dy = P2.y - P1.y; - IMPLOT_NORMALIZE2F_OVER_ZERO(dx, dy); - dx *= half_weight; - dy *= half_weight; - draw_list._VtxWritePtr[0].pos.x = P1.x + dy; - draw_list._VtxWritePtr[0].pos.y = P1.y - dx; - draw_list._VtxWritePtr[0].uv = tex_uv0; - draw_list._VtxWritePtr[0].col = col; - draw_list._VtxWritePtr[1].pos.x = P2.x + dy; - draw_list._VtxWritePtr[1].pos.y = P2.y - dx; - draw_list._VtxWritePtr[1].uv = tex_uv0; - draw_list._VtxWritePtr[1].col = col; - draw_list._VtxWritePtr[2].pos.x = P2.x - dy; - draw_list._VtxWritePtr[2].pos.y = P2.y + dx; - draw_list._VtxWritePtr[2].uv = tex_uv1; - draw_list._VtxWritePtr[2].col = col; - draw_list._VtxWritePtr[3].pos.x = P1.x - dy; - draw_list._VtxWritePtr[3].pos.y = P1.y + dx; - draw_list._VtxWritePtr[3].uv = tex_uv1; - draw_list._VtxWritePtr[3].col = col; - draw_list._VtxWritePtr += 4; - draw_list._IdxWritePtr[0] = (ImDrawIdx)(draw_list._VtxCurrentIdx); - draw_list._IdxWritePtr[1] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 1); - draw_list._IdxWritePtr[2] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 2); - draw_list._IdxWritePtr[3] = (ImDrawIdx)(draw_list._VtxCurrentIdx); - draw_list._IdxWritePtr[4] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 2); - draw_list._IdxWritePtr[5] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 3); - draw_list._IdxWritePtr += 6; - draw_list._VtxCurrentIdx += 4; -} - -IMPLOT_INLINE void PrimRectFill(ImDrawList& draw_list, const ImVec2& Pmin, const ImVec2& Pmax, ImU32 col, const ImVec2& uv) { - draw_list._VtxWritePtr[0].pos = Pmin; - draw_list._VtxWritePtr[0].uv = uv; - draw_list._VtxWritePtr[0].col = col; - draw_list._VtxWritePtr[1].pos = Pmax; - draw_list._VtxWritePtr[1].uv = uv; - draw_list._VtxWritePtr[1].col = col; - draw_list._VtxWritePtr[2].pos.x = Pmin.x; - draw_list._VtxWritePtr[2].pos.y = Pmax.y; - draw_list._VtxWritePtr[2].uv = uv; - draw_list._VtxWritePtr[2].col = col; - draw_list._VtxWritePtr[3].pos.x = Pmax.x; - draw_list._VtxWritePtr[3].pos.y = Pmin.y; - draw_list._VtxWritePtr[3].uv = uv; - draw_list._VtxWritePtr[3].col = col; - draw_list._VtxWritePtr += 4; - draw_list._IdxWritePtr[0] = (ImDrawIdx)(draw_list._VtxCurrentIdx); - draw_list._IdxWritePtr[1] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 1); - draw_list._IdxWritePtr[2] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 2); - draw_list._IdxWritePtr[3] = (ImDrawIdx)(draw_list._VtxCurrentIdx); - draw_list._IdxWritePtr[4] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 1); - draw_list._IdxWritePtr[5] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 3); - draw_list._IdxWritePtr += 6; - draw_list._VtxCurrentIdx += 4; -} - -IMPLOT_INLINE void PrimRectLine(ImDrawList& draw_list, const ImVec2& Pmin, const ImVec2& Pmax, float weight, ImU32 col, const ImVec2& uv) { - - draw_list._VtxWritePtr[0].pos.x = Pmin.x; - draw_list._VtxWritePtr[0].pos.y = Pmin.y; - draw_list._VtxWritePtr[0].uv = uv; - draw_list._VtxWritePtr[0].col = col; - - draw_list._VtxWritePtr[1].pos.x = Pmin.x; - draw_list._VtxWritePtr[1].pos.y = Pmax.y; - draw_list._VtxWritePtr[1].uv = uv; - draw_list._VtxWritePtr[1].col = col; - - draw_list._VtxWritePtr[2].pos.x = Pmax.x; - draw_list._VtxWritePtr[2].pos.y = Pmax.y; - draw_list._VtxWritePtr[2].uv = uv; - draw_list._VtxWritePtr[2].col = col; - - draw_list._VtxWritePtr[3].pos.x = Pmax.x; - draw_list._VtxWritePtr[3].pos.y = Pmin.y; - draw_list._VtxWritePtr[3].uv = uv; - draw_list._VtxWritePtr[3].col = col; - - draw_list._VtxWritePtr[4].pos.x = Pmin.x + weight; - draw_list._VtxWritePtr[4].pos.y = Pmin.y + weight; - draw_list._VtxWritePtr[4].uv = uv; - draw_list._VtxWritePtr[4].col = col; - - draw_list._VtxWritePtr[5].pos.x = Pmin.x + weight; - draw_list._VtxWritePtr[5].pos.y = Pmax.y - weight; - draw_list._VtxWritePtr[5].uv = uv; - draw_list._VtxWritePtr[5].col = col; - - draw_list._VtxWritePtr[6].pos.x = Pmax.x - weight; - draw_list._VtxWritePtr[6].pos.y = Pmax.y - weight; - draw_list._VtxWritePtr[6].uv = uv; - draw_list._VtxWritePtr[6].col = col; - - draw_list._VtxWritePtr[7].pos.x = Pmax.x - weight; - draw_list._VtxWritePtr[7].pos.y = Pmin.y + weight; - draw_list._VtxWritePtr[7].uv = uv; - draw_list._VtxWritePtr[7].col = col; - - draw_list._VtxWritePtr += 8; - - draw_list._IdxWritePtr[0] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 0); - draw_list._IdxWritePtr[1] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 1); - draw_list._IdxWritePtr[2] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 5); - draw_list._IdxWritePtr += 3; - - draw_list._IdxWritePtr[0] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 0); - draw_list._IdxWritePtr[1] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 5); - draw_list._IdxWritePtr[2] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 4); - draw_list._IdxWritePtr += 3; - - draw_list._IdxWritePtr[0] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 1); - draw_list._IdxWritePtr[1] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 2); - draw_list._IdxWritePtr[2] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 6); - draw_list._IdxWritePtr += 3; - - draw_list._IdxWritePtr[0] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 1); - draw_list._IdxWritePtr[1] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 6); - draw_list._IdxWritePtr[2] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 5); - draw_list._IdxWritePtr += 3; - - draw_list._IdxWritePtr[0] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 2); - draw_list._IdxWritePtr[1] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 3); - draw_list._IdxWritePtr[2] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 7); - draw_list._IdxWritePtr += 3; - - draw_list._IdxWritePtr[0] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 2); - draw_list._IdxWritePtr[1] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 7); - draw_list._IdxWritePtr[2] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 6); - draw_list._IdxWritePtr += 3; - - draw_list._IdxWritePtr[0] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 3); - draw_list._IdxWritePtr[1] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 0); - draw_list._IdxWritePtr[2] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 4); - draw_list._IdxWritePtr += 3; - - draw_list._IdxWritePtr[0] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 3); - draw_list._IdxWritePtr[1] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 4); - draw_list._IdxWritePtr[2] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 7); - draw_list._IdxWritePtr += 3; - - draw_list._VtxCurrentIdx += 8; -} - - -//----------------------------------------------------------------------------- -// [SECTION] Item Utils -//----------------------------------------------------------------------------- - -ImPlotItem* RegisterOrGetItem(const char* label_id, ImPlotItemFlags flags, bool* just_created) { - ImPlotContext& gp = *GImPlot; - ImPlotItemGroup& Items = *gp.CurrentItems; - ImGuiID id = Items.GetItemID(label_id); - if (just_created != nullptr) - *just_created = Items.GetItem(id) == nullptr; - ImPlotItem* item = Items.GetOrAddItem(id); - if (item->SeenThisFrame) - return item; - item->SeenThisFrame = true; - int idx = Items.GetItemIndex(item); - item->ID = id; - if (!ImHasFlag(flags, ImPlotItemFlags_NoLegend) && ImGui::FindRenderedTextEnd(label_id, nullptr) != label_id) { - Items.Legend.Indices.push_back(idx); - item->NameOffset = Items.Legend.Labels.size(); - Items.Legend.Labels.append(label_id, label_id + strlen(label_id) + 1); - } - else { - item->Show = true; - } - return item; -} - -ImPlotItem* GetItem(const char* label_id) { - ImPlotContext& gp = *GImPlot; - return gp.CurrentItems->GetItem(label_id); -} - -bool IsItemHidden(const char* label_id) { - ImPlotItem* item = GetItem(label_id); - return item != nullptr && !item->Show; -} - -ImPlotItem* GetCurrentItem() { - ImPlotContext& gp = *GImPlot; - return gp.CurrentItem; -} - -void SetNextLineStyle(const ImVec4& col, float weight) { - ImPlotContext& gp = *GImPlot; - gp.NextItemData.Colors[ImPlotCol_Line] = col; - gp.NextItemData.LineWeight = weight; -} - -void SetNextFillStyle(const ImVec4& col, float alpha) { - ImPlotContext& gp = *GImPlot; - gp.NextItemData.Colors[ImPlotCol_Fill] = col; - gp.NextItemData.FillAlpha = alpha; -} - -void SetNextMarkerStyle(ImPlotMarker marker, float size, const ImVec4& fill, float weight, const ImVec4& outline) { - ImPlotContext& gp = *GImPlot; - gp.NextItemData.Marker = marker; - gp.NextItemData.Colors[ImPlotCol_MarkerFill] = fill; - gp.NextItemData.MarkerSize = size; - gp.NextItemData.Colors[ImPlotCol_MarkerOutline] = outline; - gp.NextItemData.MarkerWeight = weight; -} - -void SetNextErrorBarStyle(const ImVec4& col, float size, float weight) { - ImPlotContext& gp = *GImPlot; - gp.NextItemData.Colors[ImPlotCol_ErrorBar] = col; - gp.NextItemData.ErrorBarSize = size; - gp.NextItemData.ErrorBarWeight = weight; -} - -ImVec4 GetLastItemColor() { - ImPlotContext& gp = *GImPlot; - if (gp.PreviousItem) - return ImGui::ColorConvertU32ToFloat4(gp.PreviousItem->Color); - return ImVec4(); -} - -void BustItemCache() { - ImPlotContext& gp = *GImPlot; - for (int p = 0; p < gp.Plots.GetBufSize(); ++p) { - ImPlotPlot& plot = *gp.Plots.GetByIndex(p); - plot.Items.Reset(); - } - for (int p = 0; p < gp.Subplots.GetBufSize(); ++p) { - ImPlotSubplot& subplot = *gp.Subplots.GetByIndex(p); - subplot.Items.Reset(); - } -} - -void BustColorCache(const char* plot_title_id) { - ImPlotContext& gp = *GImPlot; - if (plot_title_id == nullptr) { - BustItemCache(); - } - else { - ImGuiID id = ImGui::GetCurrentWindow()->GetID(plot_title_id); - ImPlotPlot* plot = gp.Plots.GetByKey(id); - if (plot != nullptr) - plot->Items.Reset(); - else { - ImPlotSubplot* subplot = gp.Subplots.GetByKey(id); - if (subplot != nullptr) - subplot->Items.Reset(); - } - } -} - -//----------------------------------------------------------------------------- -// [SECTION] BeginItem / EndItem -//----------------------------------------------------------------------------- - -static const float ITEM_HIGHLIGHT_LINE_SCALE = 2.0f; -static const float ITEM_HIGHLIGHT_MARK_SCALE = 1.25f; - -// Begins a new item. Returns false if the item should not be plotted. -bool BeginItem(const char* label_id, ImPlotItemFlags flags, ImPlotCol recolor_from) { - ImPlotContext& gp = *GImPlot; - IM_ASSERT_USER_ERROR(gp.CurrentPlot != nullptr, "PlotX() needs to be called between BeginPlot() and EndPlot()!"); - SetupLock(); - bool just_created; - ImPlotItem* item = RegisterOrGetItem(label_id, flags, &just_created); - // set current item - gp.CurrentItem = item; - ImPlotNextItemData& s = gp.NextItemData; - // set/override item color - if (recolor_from != -1) { - if (!IsColorAuto(s.Colors[recolor_from])) - item->Color = ImGui::ColorConvertFloat4ToU32(s.Colors[recolor_from]); - else if (!IsColorAuto(gp.Style.Colors[recolor_from])) - item->Color = ImGui::ColorConvertFloat4ToU32(gp.Style.Colors[recolor_from]); - else if (just_created) - item->Color = NextColormapColorU32(); - } - else if (just_created) { - item->Color = NextColormapColorU32(); - } - // hide/show item - if (gp.NextItemData.HasHidden) { - if (just_created || gp.NextItemData.HiddenCond == ImGuiCond_Always) - item->Show = !gp.NextItemData.Hidden; - } - if (!item->Show) { - // reset next item data - gp.NextItemData.Reset(); - gp.PreviousItem = item; - gp.CurrentItem = nullptr; - return false; - } - else { - ImVec4 item_color = ImGui::ColorConvertU32ToFloat4(item->Color); - // stage next item colors - s.Colors[ImPlotCol_Line] = IsColorAuto(s.Colors[ImPlotCol_Line]) ? ( IsColorAuto(ImPlotCol_Line) ? item_color : gp.Style.Colors[ImPlotCol_Line] ) : s.Colors[ImPlotCol_Line]; - s.Colors[ImPlotCol_Fill] = IsColorAuto(s.Colors[ImPlotCol_Fill]) ? ( IsColorAuto(ImPlotCol_Fill) ? item_color : gp.Style.Colors[ImPlotCol_Fill] ) : s.Colors[ImPlotCol_Fill]; - s.Colors[ImPlotCol_MarkerOutline] = IsColorAuto(s.Colors[ImPlotCol_MarkerOutline]) ? ( IsColorAuto(ImPlotCol_MarkerOutline) ? s.Colors[ImPlotCol_Line] : gp.Style.Colors[ImPlotCol_MarkerOutline] ) : s.Colors[ImPlotCol_MarkerOutline]; - s.Colors[ImPlotCol_MarkerFill] = IsColorAuto(s.Colors[ImPlotCol_MarkerFill]) ? ( IsColorAuto(ImPlotCol_MarkerFill) ? s.Colors[ImPlotCol_Line] : gp.Style.Colors[ImPlotCol_MarkerFill] ) : s.Colors[ImPlotCol_MarkerFill]; - s.Colors[ImPlotCol_ErrorBar] = IsColorAuto(s.Colors[ImPlotCol_ErrorBar]) ? ( GetStyleColorVec4(ImPlotCol_ErrorBar) ) : s.Colors[ImPlotCol_ErrorBar]; - // stage next item style vars - s.LineWeight = s.LineWeight < 0 ? gp.Style.LineWeight : s.LineWeight; - s.Marker = s.Marker < 0 ? gp.Style.Marker : s.Marker; - s.MarkerSize = s.MarkerSize < 0 ? gp.Style.MarkerSize : s.MarkerSize; - s.MarkerWeight = s.MarkerWeight < 0 ? gp.Style.MarkerWeight : s.MarkerWeight; - s.FillAlpha = s.FillAlpha < 0 ? gp.Style.FillAlpha : s.FillAlpha; - s.ErrorBarSize = s.ErrorBarSize < 0 ? gp.Style.ErrorBarSize : s.ErrorBarSize; - s.ErrorBarWeight = s.ErrorBarWeight < 0 ? gp.Style.ErrorBarWeight : s.ErrorBarWeight; - s.DigitalBitHeight = s.DigitalBitHeight < 0 ? gp.Style.DigitalBitHeight : s.DigitalBitHeight; - s.DigitalBitGap = s.DigitalBitGap < 0 ? gp.Style.DigitalBitGap : s.DigitalBitGap; - // apply alpha modifier(s) - s.Colors[ImPlotCol_Fill].w *= s.FillAlpha; - s.Colors[ImPlotCol_MarkerFill].w *= s.FillAlpha; // TODO: this should be separate, if it at all - // apply highlight mods - if (item->LegendHovered) { - if (!ImHasFlag(gp.CurrentItems->Legend.Flags, ImPlotLegendFlags_NoHighlightItem)) { - s.LineWeight *= ITEM_HIGHLIGHT_LINE_SCALE; - s.MarkerSize *= ITEM_HIGHLIGHT_MARK_SCALE; - s.MarkerWeight *= ITEM_HIGHLIGHT_LINE_SCALE; - // TODO: how to highlight fills? - } - if (!ImHasFlag(gp.CurrentItems->Legend.Flags, ImPlotLegendFlags_NoHighlightAxis)) { - if (gp.CurrentPlot->EnabledAxesX() > 1) - gp.CurrentPlot->Axes[gp.CurrentPlot->CurrentX].ColorHiLi = item->Color; - if (gp.CurrentPlot->EnabledAxesY() > 1) - gp.CurrentPlot->Axes[gp.CurrentPlot->CurrentY].ColorHiLi = item->Color; - } - } - // set render flags - s.RenderLine = s.Colors[ImPlotCol_Line].w > 0 && s.LineWeight > 0; - s.RenderFill = s.Colors[ImPlotCol_Fill].w > 0; - s.RenderMarkerFill = s.Colors[ImPlotCol_MarkerFill].w > 0; - s.RenderMarkerLine = s.Colors[ImPlotCol_MarkerOutline].w > 0 && s.MarkerWeight > 0; - // push rendering clip rect - PushPlotClipRect(); - return true; - } -} - -// Ends an item (call only if BeginItem returns true) -void EndItem() { - ImPlotContext& gp = *GImPlot; - // pop rendering clip rect - PopPlotClipRect(); - // reset next item data - gp.NextItemData.Reset(); - // set current item - gp.PreviousItem = gp.CurrentItem; - gp.CurrentItem = nullptr; -} - -//----------------------------------------------------------------------------- -// [SECTION] Indexers -//----------------------------------------------------------------------------- - -template -IMPLOT_INLINE T IndexData(const T* data, int idx, int count, int offset, int stride) { - const int s = ((offset == 0) << 0) | ((stride == sizeof(T)) << 1); - switch (s) { - case 3 : return data[idx]; - case 2 : return data[(offset + idx) % count]; - case 1 : return *(const T*)(const void*)((const unsigned char*)data + (size_t)((idx) ) * stride); - case 0 : return *(const T*)(const void*)((const unsigned char*)data + (size_t)((offset + idx) % count) * stride); - default: return T(0); - } -} - -template -struct IndexerIdx { - IndexerIdx(const T* data, int count, int offset = 0, int stride = sizeof(T)) : - Data(data), - Count(count), - Offset(count ? ImPosMod(offset, count) : 0), - Stride(stride) - { } - template IMPLOT_INLINE double operator()(I idx) const { - return (double)IndexData(Data, idx, Count, Offset, Stride); - } - const T* Data; - int Count; - int Offset; - int Stride; -}; - -template -struct IndexerAdd { - IndexerAdd(const _Indexer1& indexer1, const _Indexer2& indexer2, double scale1 = 1, double scale2 = 1) - : Indexer1(indexer1), - Indexer2(indexer2), - Scale1(scale1), - Scale2(scale2), - Count(ImMin(Indexer1.Count, Indexer2.Count)) - { } - template IMPLOT_INLINE double operator()(I idx) const { - return Scale1 * Indexer1(idx) + Scale2 * Indexer2(idx); - } - const _Indexer1& Indexer1; - const _Indexer2& Indexer2; - double Scale1; - double Scale2; - int Count; -}; - -struct IndexerLin { - IndexerLin(double m, double b) : M(m), B(b) { } - template IMPLOT_INLINE double operator()(I idx) const { - return M * idx + B; - } - const double M; - const double B; -}; - -struct IndexerConst { - IndexerConst(double ref) : Ref(ref) { } - template IMPLOT_INLINE double operator()(I) const { return Ref; } - const double Ref; -}; - -//----------------------------------------------------------------------------- -// [SECTION] Getters -//----------------------------------------------------------------------------- - -template -struct GetterXY { - GetterXY(_IndexerX x, _IndexerY y, int count) : IndxerX(x), IndxerY(y), Count(count) { } - template IMPLOT_INLINE ImPlotPoint operator()(I idx) const { - return ImPlotPoint(IndxerX(idx),IndxerY(idx)); - } - const _IndexerX IndxerX; - const _IndexerY IndxerY; - const int Count; -}; - -/// Interprets a user's function pointer as ImPlotPoints -struct GetterFuncPtr { - GetterFuncPtr(ImPlotGetter getter, void* data, int count) : - Getter(getter), - Data(data), - Count(count) - { } - template IMPLOT_INLINE ImPlotPoint operator()(I idx) const { - return Getter(idx, Data); - } - ImPlotGetter Getter; - void* const Data; - const int Count; -}; - -template -struct GetterOverrideX { - GetterOverrideX(_Getter getter, double x) : Getter(getter), X(x), Count(getter.Count) { } - template IMPLOT_INLINE ImPlotPoint operator()(I idx) const { - ImPlotPoint p = Getter(idx); - p.x = X; - return p; - } - const _Getter Getter; - const double X; - const int Count; -}; - -template -struct GetterOverrideY { - GetterOverrideY(_Getter getter, double y) : Getter(getter), Y(y), Count(getter.Count) { } - template IMPLOT_INLINE ImPlotPoint operator()(I idx) const { - ImPlotPoint p = Getter(idx); - p.y = Y; - return p; - } - const _Getter Getter; - const double Y; - const int Count; -}; - -template -struct GetterLoop { - GetterLoop(_Getter getter) : Getter(getter), Count(getter.Count + 1) { } - template IMPLOT_INLINE ImPlotPoint operator()(I idx) const { - idx = idx % (Count - 1); - return Getter(idx); - } - const _Getter Getter; - const int Count; -}; - -template -struct GetterError { - GetterError(const T* xs, const T* ys, const T* neg, const T* pos, int count, int offset, int stride) : - Xs(xs), - Ys(ys), - Neg(neg), - Pos(pos), - Count(count), - Offset(count ? ImPosMod(offset, count) : 0), - Stride(stride) - { } - template IMPLOT_INLINE ImPlotPointError operator()(I idx) const { - return ImPlotPointError((double)IndexData(Xs, idx, Count, Offset, Stride), - (double)IndexData(Ys, idx, Count, Offset, Stride), - (double)IndexData(Neg, idx, Count, Offset, Stride), - (double)IndexData(Pos, idx, Count, Offset, Stride)); - } - const T* const Xs; - const T* const Ys; - const T* const Neg; - const T* const Pos; - const int Count; - const int Offset; - const int Stride; -}; - -//----------------------------------------------------------------------------- -// [SECTION] Fitters -//----------------------------------------------------------------------------- - -template -struct Fitter1 { - Fitter1(const _Getter1& getter) : Getter(getter) { } - void Fit(ImPlotAxis& x_axis, ImPlotAxis& y_axis) const { - for (int i = 0; i < Getter.Count; ++i) { - ImPlotPoint p = Getter(i); - x_axis.ExtendFitWith(y_axis, p.x, p.y); - y_axis.ExtendFitWith(x_axis, p.y, p.x); - } - } - const _Getter1& Getter; -}; - -template -struct FitterX { - FitterX(const _Getter1& getter) : Getter(getter) { } - void Fit(ImPlotAxis& x_axis, ImPlotAxis&) const { - for (int i = 0; i < Getter.Count; ++i) { - ImPlotPoint p = Getter(i); - x_axis.ExtendFit(p.x); - } - } - const _Getter1& Getter; -}; - -template -struct FitterY { - FitterY(const _Getter1& getter) : Getter(getter) { } - void Fit(ImPlotAxis&, ImPlotAxis& y_axis) const { - for (int i = 0; i < Getter.Count; ++i) { - ImPlotPoint p = Getter(i); - y_axis.ExtendFit(p.y); - } - } - const _Getter1& Getter; -}; - -template -struct Fitter2 { - Fitter2(const _Getter1& getter1, const _Getter2& getter2) : Getter1(getter1), Getter2(getter2) { } - void Fit(ImPlotAxis& x_axis, ImPlotAxis& y_axis) const { - for (int i = 0; i < Getter1.Count; ++i) { - ImPlotPoint p = Getter1(i); - x_axis.ExtendFitWith(y_axis, p.x, p.y); - y_axis.ExtendFitWith(x_axis, p.y, p.x); - } - for (int i = 0; i < Getter2.Count; ++i) { - ImPlotPoint p = Getter2(i); - x_axis.ExtendFitWith(y_axis, p.x, p.y); - y_axis.ExtendFitWith(x_axis, p.y, p.x); - } - } - const _Getter1& Getter1; - const _Getter2& Getter2; -}; - -template -struct FitterBarV { - FitterBarV(const _Getter1& getter1, const _Getter2& getter2, double width) : - Getter1(getter1), - Getter2(getter2), - HalfWidth(width*0.5) - { } - void Fit(ImPlotAxis& x_axis, ImPlotAxis& y_axis) const { - int count = ImMin(Getter1.Count, Getter2.Count); - for (int i = 0; i < count; ++i) { - ImPlotPoint p1 = Getter1(i); p1.x -= HalfWidth; - ImPlotPoint p2 = Getter2(i); p2.x += HalfWidth; - x_axis.ExtendFitWith(y_axis, p1.x, p1.y); - y_axis.ExtendFitWith(x_axis, p1.y, p1.x); - x_axis.ExtendFitWith(y_axis, p2.x, p2.y); - y_axis.ExtendFitWith(x_axis, p2.y, p2.x); - } - } - const _Getter1& Getter1; - const _Getter2& Getter2; - const double HalfWidth; -}; - -template -struct FitterBarH { - FitterBarH(const _Getter1& getter1, const _Getter2& getter2, double height) : - Getter1(getter1), - Getter2(getter2), - HalfHeight(height*0.5) - { } - void Fit(ImPlotAxis& x_axis, ImPlotAxis& y_axis) const { - int count = ImMin(Getter1.Count, Getter2.Count); - for (int i = 0; i < count; ++i) { - ImPlotPoint p1 = Getter1(i); p1.y -= HalfHeight; - ImPlotPoint p2 = Getter2(i); p2.y += HalfHeight; - x_axis.ExtendFitWith(y_axis, p1.x, p1.y); - y_axis.ExtendFitWith(x_axis, p1.y, p1.x); - x_axis.ExtendFitWith(y_axis, p2.x, p2.y); - y_axis.ExtendFitWith(x_axis, p2.y, p2.x); - } - } - const _Getter1& Getter1; - const _Getter2& Getter2; - const double HalfHeight; -}; - -struct FitterRect { - FitterRect(const ImPlotPoint& pmin, const ImPlotPoint& pmax) : - Pmin(pmin), - Pmax(pmax) - { } - FitterRect(const ImPlotRect& rect) : - FitterRect(rect.Min(), rect.Max()) - { } - void Fit(ImPlotAxis& x_axis, ImPlotAxis& y_axis) const { - x_axis.ExtendFitWith(y_axis, Pmin.x, Pmin.y); - y_axis.ExtendFitWith(x_axis, Pmin.y, Pmin.x); - x_axis.ExtendFitWith(y_axis, Pmax.x, Pmax.y); - y_axis.ExtendFitWith(x_axis, Pmax.y, Pmax.x); - } - const ImPlotPoint Pmin; - const ImPlotPoint Pmax; -}; - -//----------------------------------------------------------------------------- -// [SECTION] Transformers -//----------------------------------------------------------------------------- - -struct Transformer1 { - Transformer1(double pixMin, double pltMin, double pltMax, double m, double scaMin, double scaMax, ImPlotTransform fwd, void* data) : - ScaMin(scaMin), - ScaMax(scaMax), - PltMin(pltMin), - PltMax(pltMax), - PixMin(pixMin), - M(m), - TransformFwd(fwd), - TransformData(data) - { } - - template IMPLOT_INLINE float operator()(T p) const { - if (TransformFwd != nullptr) { - double s = TransformFwd(p, TransformData); - double t = (s - ScaMin) / (ScaMax - ScaMin); - p = PltMin + (PltMax - PltMin) * t; - } - return (float)(PixMin + M * (p - PltMin)); - } - - double ScaMin, ScaMax, PltMin, PltMax, PixMin, M; - ImPlotTransform TransformFwd; - void* TransformData; -}; - -struct Transformer2 { - Transformer2(const ImPlotAxis& x_axis, const ImPlotAxis& y_axis) : - Tx(x_axis.PixelMin, - x_axis.Range.Min, - x_axis.Range.Max, - x_axis.ScaleToPixel, - x_axis.ScaleMin, - x_axis.ScaleMax, - x_axis.TransformForward, - x_axis.TransformData), - Ty(y_axis.PixelMin, - y_axis.Range.Min, - y_axis.Range.Max, - y_axis.ScaleToPixel, - y_axis.ScaleMin, - y_axis.ScaleMax, - y_axis.TransformForward, - y_axis.TransformData) - { } - - Transformer2(const ImPlotPlot& plot) : - Transformer2(plot.Axes[plot.CurrentX], plot.Axes[plot.CurrentY]) - { } - - Transformer2() : - Transformer2(*GImPlot->CurrentPlot) - { } - - template IMPLOT_INLINE ImVec2 operator()(const P& plt) const { - ImVec2 out; - out.x = Tx(plt.x); - out.y = Ty(plt.y); - return out; - } - - template IMPLOT_INLINE ImVec2 operator()(T x, T y) const { - ImVec2 out; - out.x = Tx(x); - out.y = Ty(y); - return out; - } - - Transformer1 Tx; - Transformer1 Ty; -}; - -//----------------------------------------------------------------------------- -// [SECTION] Renderers -//----------------------------------------------------------------------------- - -struct RendererBase { - RendererBase(int prims, int idx_consumed, int vtx_consumed) : - Prims(prims), - IdxConsumed(idx_consumed), - VtxConsumed(vtx_consumed) - { } - const int Prims; - Transformer2 Transformer; - const int IdxConsumed; - const int VtxConsumed; -}; - -template -struct RendererLineStrip : RendererBase { - RendererLineStrip(const _Getter& getter, ImU32 col, float weight) : - RendererBase(getter.Count - 1, 6, 4), - Getter(getter), - Col(col), - HalfWeight(ImMax(1.0f,weight)*0.5f) - { - P1 = this->Transformer(Getter(0)); - } - void Init(ImDrawList& draw_list) const { - GetLineRenderProps(draw_list, HalfWeight, UV0, UV1); - } - IMPLOT_INLINE bool Render(ImDrawList& draw_list, const ImRect& cull_rect, int prim) const { - ImVec2 P2 = this->Transformer(Getter(prim + 1)); - if (!cull_rect.Overlaps(ImRect(ImMin(P1, P2), ImMax(P1, P2)))) { - P1 = P2; - return false; - } - PrimLine(draw_list,P1,P2,HalfWeight,Col,UV0,UV1); - P1 = P2; - return true; - } - const _Getter& Getter; - const ImU32 Col; - mutable float HalfWeight; - mutable ImVec2 P1; - mutable ImVec2 UV0; - mutable ImVec2 UV1; -}; - -template -struct RendererLineStripSkip : RendererBase { - RendererLineStripSkip(const _Getter& getter, ImU32 col, float weight) : - RendererBase(getter.Count - 1, 6, 4), - Getter(getter), - Col(col), - HalfWeight(ImMax(1.0f,weight)*0.5f) - { - P1 = this->Transformer(Getter(0)); - } - void Init(ImDrawList& draw_list) const { - GetLineRenderProps(draw_list, HalfWeight, UV0, UV1); - } - IMPLOT_INLINE bool Render(ImDrawList& draw_list, const ImRect& cull_rect, int prim) const { - ImVec2 P2 = this->Transformer(Getter(prim + 1)); - if (!cull_rect.Overlaps(ImRect(ImMin(P1, P2), ImMax(P1, P2)))) { - if (!ImNan(P2.x) && !ImNan(P2.y)) - P1 = P2; - return false; - } - PrimLine(draw_list,P1,P2,HalfWeight,Col,UV0,UV1); - if (!ImNan(P2.x) && !ImNan(P2.y)) - P1 = P2; - return true; - } - const _Getter& Getter; - const ImU32 Col; - mutable float HalfWeight; - mutable ImVec2 P1; - mutable ImVec2 UV0; - mutable ImVec2 UV1; -}; - -template -struct RendererLineSegments1 : RendererBase { - RendererLineSegments1(const _Getter& getter, ImU32 col, float weight) : - RendererBase(getter.Count / 2, 6, 4), - Getter(getter), - Col(col), - HalfWeight(ImMax(1.0f,weight)*0.5f) - { } - void Init(ImDrawList& draw_list) const { - GetLineRenderProps(draw_list, HalfWeight, UV0, UV1); - } - IMPLOT_INLINE bool Render(ImDrawList& draw_list, const ImRect& cull_rect, int prim) const { - ImVec2 P1 = this->Transformer(Getter(prim*2+0)); - ImVec2 P2 = this->Transformer(Getter(prim*2+1)); - if (!cull_rect.Overlaps(ImRect(ImMin(P1, P2), ImMax(P1, P2)))) - return false; - PrimLine(draw_list,P1,P2,HalfWeight,Col,UV0,UV1); - return true; - } - const _Getter& Getter; - const ImU32 Col; - mutable float HalfWeight; - mutable ImVec2 UV0; - mutable ImVec2 UV1; -}; - -template -struct RendererLineSegments2 : RendererBase { - RendererLineSegments2(const _Getter1& getter1, const _Getter2& getter2, ImU32 col, float weight) : - RendererBase(ImMin(getter1.Count, getter1.Count), 6, 4), - Getter1(getter1), - Getter2(getter2), - Col(col), - HalfWeight(ImMax(1.0f,weight)*0.5f) - {} - void Init(ImDrawList& draw_list) const { - GetLineRenderProps(draw_list, HalfWeight, UV0, UV1); - } - IMPLOT_INLINE bool Render(ImDrawList& draw_list, const ImRect& cull_rect, int prim) const { - ImVec2 P1 = this->Transformer(Getter1(prim)); - ImVec2 P2 = this->Transformer(Getter2(prim)); - if (!cull_rect.Overlaps(ImRect(ImMin(P1, P2), ImMax(P1, P2)))) - return false; - PrimLine(draw_list,P1,P2,HalfWeight,Col,UV0,UV1); - return true; - } - const _Getter1& Getter1; - const _Getter2& Getter2; - const ImU32 Col; - mutable float HalfWeight; - mutable ImVec2 UV0; - mutable ImVec2 UV1; -}; - -template -struct RendererBarsFillV : RendererBase { - RendererBarsFillV(const _Getter1& getter1, const _Getter2& getter2, ImU32 col, double width) : - RendererBase(ImMin(getter1.Count, getter1.Count), 6, 4), - Getter1(getter1), - Getter2(getter2), - Col(col), - HalfWidth(width/2) - {} - void Init(ImDrawList& draw_list) const { - UV = draw_list._Data->TexUvWhitePixel; - } - IMPLOT_INLINE bool Render(ImDrawList& draw_list, const ImRect& cull_rect, int prim) const { - ImPlotPoint p1 = Getter1(prim); - ImPlotPoint p2 = Getter2(prim); - p1.x += HalfWidth; - p2.x -= HalfWidth; - ImVec2 P1 = this->Transformer(p1); - ImVec2 P2 = this->Transformer(p2); - float width_px = ImAbs(P1.x-P2.x); - if (width_px < 1.0f) { - P1.x += P1.x > P2.x ? (1-width_px) / 2 : (width_px-1) / 2; - P2.x += P2.x > P1.x ? (1-width_px) / 2 : (width_px-1) / 2; - } - ImVec2 PMin = ImMin(P1, P2); - ImVec2 PMax = ImMax(P1, P2); - if (!cull_rect.Overlaps(ImRect(PMin, PMax))) - return false; - PrimRectFill(draw_list,PMin,PMax,Col,UV); - return true; - } - const _Getter1& Getter1; - const _Getter2& Getter2; - const ImU32 Col; - const double HalfWidth; - mutable ImVec2 UV; -}; - -template -struct RendererBarsFillH : RendererBase { - RendererBarsFillH(const _Getter1& getter1, const _Getter2& getter2, ImU32 col, double height) : - RendererBase(ImMin(getter1.Count, getter1.Count), 6, 4), - Getter1(getter1), - Getter2(getter2), - Col(col), - HalfHeight(height/2) - {} - void Init(ImDrawList& draw_list) const { - UV = draw_list._Data->TexUvWhitePixel; - } - IMPLOT_INLINE bool Render(ImDrawList& draw_list, const ImRect& cull_rect, int prim) const { - ImPlotPoint p1 = Getter1(prim); - ImPlotPoint p2 = Getter2(prim); - p1.y += HalfHeight; - p2.y -= HalfHeight; - ImVec2 P1 = this->Transformer(p1); - ImVec2 P2 = this->Transformer(p2); - float height_px = ImAbs(P1.y-P2.y); - if (height_px < 1.0f) { - P1.y += P1.y > P2.y ? (1-height_px) / 2 : (height_px-1) / 2; - P2.y += P2.y > P1.y ? (1-height_px) / 2 : (height_px-1) / 2; - } - ImVec2 PMin = ImMin(P1, P2); - ImVec2 PMax = ImMax(P1, P2); - if (!cull_rect.Overlaps(ImRect(PMin, PMax))) - return false; - PrimRectFill(draw_list,PMin,PMax,Col,UV); - return true; - } - const _Getter1& Getter1; - const _Getter2& Getter2; - const ImU32 Col; - const double HalfHeight; - mutable ImVec2 UV; -}; - -template -struct RendererBarsLineV : RendererBase { - RendererBarsLineV(const _Getter1& getter1, const _Getter2& getter2, ImU32 col, double width, float weight) : - RendererBase(ImMin(getter1.Count, getter1.Count), 24, 8), - Getter1(getter1), - Getter2(getter2), - Col(col), - HalfWidth(width/2), - Weight(weight) - {} - void Init(ImDrawList& draw_list) const { - UV = draw_list._Data->TexUvWhitePixel; - } - IMPLOT_INLINE bool Render(ImDrawList& draw_list, const ImRect& cull_rect, int prim) const { - ImPlotPoint p1 = Getter1(prim); - ImPlotPoint p2 = Getter2(prim); - p1.x += HalfWidth; - p2.x -= HalfWidth; - ImVec2 P1 = this->Transformer(p1); - ImVec2 P2 = this->Transformer(p2); - float width_px = ImAbs(P1.x-P2.x); - if (width_px < 1.0f) { - P1.x += P1.x > P2.x ? (1-width_px) / 2 : (width_px-1) / 2; - P2.x += P2.x > P1.x ? (1-width_px) / 2 : (width_px-1) / 2; - } - ImVec2 PMin = ImMin(P1, P2); - ImVec2 PMax = ImMax(P1, P2); - if (!cull_rect.Overlaps(ImRect(PMin, PMax))) - return false; - PrimRectLine(draw_list,PMin,PMax,Weight,Col,UV); - return true; - } - const _Getter1& Getter1; - const _Getter2& Getter2; - const ImU32 Col; - const double HalfWidth; - const float Weight; - mutable ImVec2 UV; -}; - -template -struct RendererBarsLineH : RendererBase { - RendererBarsLineH(const _Getter1& getter1, const _Getter2& getter2, ImU32 col, double height, float weight) : - RendererBase(ImMin(getter1.Count, getter1.Count), 24, 8), - Getter1(getter1), - Getter2(getter2), - Col(col), - HalfHeight(height/2), - Weight(weight) - {} - void Init(ImDrawList& draw_list) const { - UV = draw_list._Data->TexUvWhitePixel; - } - IMPLOT_INLINE bool Render(ImDrawList& draw_list, const ImRect& cull_rect, int prim) const { - ImPlotPoint p1 = Getter1(prim); - ImPlotPoint p2 = Getter2(prim); - p1.y += HalfHeight; - p2.y -= HalfHeight; - ImVec2 P1 = this->Transformer(p1); - ImVec2 P2 = this->Transformer(p2); - float height_px = ImAbs(P1.y-P2.y); - if (height_px < 1.0f) { - P1.y += P1.y > P2.y ? (1-height_px) / 2 : (height_px-1) / 2; - P2.y += P2.y > P1.y ? (1-height_px) / 2 : (height_px-1) / 2; - } - ImVec2 PMin = ImMin(P1, P2); - ImVec2 PMax = ImMax(P1, P2); - if (!cull_rect.Overlaps(ImRect(PMin, PMax))) - return false; - PrimRectLine(draw_list,PMin,PMax,Weight,Col,UV); - return true; - } - const _Getter1& Getter1; - const _Getter2& Getter2; - const ImU32 Col; - const double HalfHeight; - const float Weight; - mutable ImVec2 UV; -}; - - -template -struct RendererStairsPre : RendererBase { - RendererStairsPre(const _Getter& getter, ImU32 col, float weight) : - RendererBase(getter.Count - 1, 12, 8), - Getter(getter), - Col(col), - HalfWeight(ImMax(1.0f,weight)*0.5f) - { - P1 = this->Transformer(Getter(0)); - } - void Init(ImDrawList& draw_list) const { - UV = draw_list._Data->TexUvWhitePixel; - } - IMPLOT_INLINE bool Render(ImDrawList& draw_list, const ImRect& cull_rect, int prim) const { - ImVec2 P2 = this->Transformer(Getter(prim + 1)); - if (!cull_rect.Overlaps(ImRect(ImMin(P1, P2), ImMax(P1, P2)))) { - P1 = P2; - return false; - } - PrimRectFill(draw_list, ImVec2(P1.x - HalfWeight, P1.y), ImVec2(P1.x + HalfWeight, P2.y), Col, UV); - PrimRectFill(draw_list, ImVec2(P1.x, P2.y + HalfWeight), ImVec2(P2.x, P2.y - HalfWeight), Col, UV); - P1 = P2; - return true; - } - const _Getter& Getter; - const ImU32 Col; - mutable float HalfWeight; - mutable ImVec2 P1; - mutable ImVec2 UV; -}; - -template -struct RendererStairsPost : RendererBase { - RendererStairsPost(const _Getter& getter, ImU32 col, float weight) : - RendererBase(getter.Count - 1, 12, 8), - Getter(getter), - Col(col), - HalfWeight(ImMax(1.0f,weight) * 0.5f) - { - P1 = this->Transformer(Getter(0)); - } - void Init(ImDrawList& draw_list) const { - UV = draw_list._Data->TexUvWhitePixel; - } - IMPLOT_INLINE bool Render(ImDrawList& draw_list, const ImRect& cull_rect, int prim) const { - ImVec2 P2 = this->Transformer(Getter(prim + 1)); - if (!cull_rect.Overlaps(ImRect(ImMin(P1, P2), ImMax(P1, P2)))) { - P1 = P2; - return false; - } - PrimRectFill(draw_list, ImVec2(P1.x, P1.y + HalfWeight), ImVec2(P2.x, P1.y - HalfWeight), Col, UV); - PrimRectFill(draw_list, ImVec2(P2.x - HalfWeight, P2.y), ImVec2(P2.x + HalfWeight, P1.y), Col, UV); - P1 = P2; - return true; - } - const _Getter& Getter; - const ImU32 Col; - mutable float HalfWeight; - mutable ImVec2 P1; - mutable ImVec2 UV; -}; - -template -struct RendererStairsPreShaded : RendererBase { - RendererStairsPreShaded(const _Getter& getter, ImU32 col) : - RendererBase(getter.Count - 1, 6, 4), - Getter(getter), - Col(col) - { - P1 = this->Transformer(Getter(0)); - Y0 = this->Transformer(ImPlotPoint(0,0)).y; - } - void Init(ImDrawList& draw_list) const { - UV = draw_list._Data->TexUvWhitePixel; - } - IMPLOT_INLINE bool Render(ImDrawList& draw_list, const ImRect& cull_rect, int prim) const { - ImVec2 P2 = this->Transformer(Getter(prim + 1)); - ImVec2 PMin(ImMin(P1.x, P2.x), ImMin(Y0, P2.y)); - ImVec2 PMax(ImMax(P1.x, P2.x), ImMax(Y0, P2.y)); - if (!cull_rect.Overlaps(ImRect(PMin, PMax))) { - P1 = P2; - return false; - } - PrimRectFill(draw_list, PMin, PMax, Col, UV); - P1 = P2; - return true; - } - const _Getter& Getter; - const ImU32 Col; - float Y0; - mutable ImVec2 P1; - mutable ImVec2 UV; -}; - -template -struct RendererStairsPostShaded : RendererBase { - RendererStairsPostShaded(const _Getter& getter, ImU32 col) : - RendererBase(getter.Count - 1, 6, 4), - Getter(getter), - Col(col) - { - P1 = this->Transformer(Getter(0)); - Y0 = this->Transformer(ImPlotPoint(0,0)).y; - } - void Init(ImDrawList& draw_list) const { - UV = draw_list._Data->TexUvWhitePixel; - } - IMPLOT_INLINE bool Render(ImDrawList& draw_list, const ImRect& cull_rect, int prim) const { - ImVec2 P2 = this->Transformer(Getter(prim + 1)); - ImVec2 PMin(ImMin(P1.x, P2.x), ImMin(P1.y, Y0)); - ImVec2 PMax(ImMax(P1.x, P2.x), ImMax(P1.y, Y0)); - if (!cull_rect.Overlaps(ImRect(PMin, PMax))) { - P1 = P2; - return false; - } - PrimRectFill(draw_list, PMin, PMax, Col, UV); - P1 = P2; - return true; - } - const _Getter& Getter; - const ImU32 Col; - float Y0; - mutable ImVec2 P1; - mutable ImVec2 UV; -}; - - - -template -struct RendererShaded : RendererBase { - RendererShaded(const _Getter1& getter1, const _Getter2& getter2, ImU32 col) : - RendererBase(ImMin(getter1.Count, getter2.Count) - 1, 6, 5), - Getter1(getter1), - Getter2(getter2), - Col(col) - { - P11 = this->Transformer(Getter1(0)); - P12 = this->Transformer(Getter2(0)); - } - void Init(ImDrawList& draw_list) const { - UV = draw_list._Data->TexUvWhitePixel; - } - IMPLOT_INLINE bool Render(ImDrawList& draw_list, const ImRect& cull_rect, int prim) const { - ImVec2 P21 = this->Transformer(Getter1(prim+1)); - ImVec2 P22 = this->Transformer(Getter2(prim+1)); - ImRect rect(ImMin(ImMin(ImMin(P11,P12),P21),P22), ImMax(ImMax(ImMax(P11,P12),P21),P22)); - if (!cull_rect.Overlaps(rect)) { - P11 = P21; - P12 = P22; - return false; - } - const int intersect = (P11.y > P12.y && P22.y > P21.y) || (P12.y > P11.y && P21.y > P22.y); - const ImVec2 intersection = intersect == 0 ? ImVec2(0,0) : Intersection(P11,P21,P12,P22); - draw_list._VtxWritePtr[0].pos = P11; - draw_list._VtxWritePtr[0].uv = UV; - draw_list._VtxWritePtr[0].col = Col; - draw_list._VtxWritePtr[1].pos = P21; - draw_list._VtxWritePtr[1].uv = UV; - draw_list._VtxWritePtr[1].col = Col; - draw_list._VtxWritePtr[2].pos = intersection; - draw_list._VtxWritePtr[2].uv = UV; - draw_list._VtxWritePtr[2].col = Col; - draw_list._VtxWritePtr[3].pos = P12; - draw_list._VtxWritePtr[3].uv = UV; - draw_list._VtxWritePtr[3].col = Col; - draw_list._VtxWritePtr[4].pos = P22; - draw_list._VtxWritePtr[4].uv = UV; - draw_list._VtxWritePtr[4].col = Col; - draw_list._VtxWritePtr += 5; - draw_list._IdxWritePtr[0] = (ImDrawIdx)(draw_list._VtxCurrentIdx); - draw_list._IdxWritePtr[1] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 1 + intersect); - draw_list._IdxWritePtr[2] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 3); - draw_list._IdxWritePtr[3] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 1); - draw_list._IdxWritePtr[4] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 4); - draw_list._IdxWritePtr[5] = (ImDrawIdx)(draw_list._VtxCurrentIdx + 3 - intersect); - draw_list._IdxWritePtr += 6; - draw_list._VtxCurrentIdx += 5; - P11 = P21; - P12 = P22; - return true; - } - const _Getter1& Getter1; - const _Getter2& Getter2; - const ImU32 Col; - mutable ImVec2 P11; - mutable ImVec2 P12; - mutable ImVec2 UV; -}; - -struct RectC { - ImPlotPoint Pos; - ImPlotPoint HalfSize; - ImU32 Color; -}; - -template -struct RendererRectC : RendererBase { - RendererRectC(const _Getter& getter) : - RendererBase(getter.Count, 6, 4), - Getter(getter) - {} - void Init(ImDrawList& draw_list) const { - UV = draw_list._Data->TexUvWhitePixel; - } - IMPLOT_INLINE bool Render(ImDrawList& draw_list, const ImRect& cull_rect, int prim) const { - RectC rect = Getter(prim); - ImVec2 P1 = this->Transformer(rect.Pos.x - rect.HalfSize.x , rect.Pos.y - rect.HalfSize.y); - ImVec2 P2 = this->Transformer(rect.Pos.x + rect.HalfSize.x , rect.Pos.y + rect.HalfSize.y); - if ((rect.Color & IM_COL32_A_MASK) == 0 || !cull_rect.Overlaps(ImRect(ImMin(P1, P2), ImMax(P1, P2)))) - return false; - PrimRectFill(draw_list,P1,P2,rect.Color,UV); - return true; - } - const _Getter& Getter; - mutable ImVec2 UV; -}; - -//----------------------------------------------------------------------------- -// [SECTION] RenderPrimitives -//----------------------------------------------------------------------------- - -/// Renders primitive shapes in bulk as efficiently as possible. -template -void RenderPrimitivesEx(const _Renderer& renderer, ImDrawList& draw_list, const ImRect& cull_rect) { - unsigned int prims = renderer.Prims; - unsigned int prims_culled = 0; - unsigned int idx = 0; - renderer.Init(draw_list); - while (prims) { - // find how many can be reserved up to end of current draw command's limit - unsigned int cnt = ImMin(prims, (MaxIdx::Value - draw_list._VtxCurrentIdx) / renderer.VtxConsumed); - // make sure at least this many elements can be rendered to avoid situations where at the end of buffer this slow path is not taken all the time - if (cnt >= ImMin(64u, prims)) { - if (prims_culled >= cnt) - prims_culled -= cnt; // reuse previous reservation - else { - // add more elements to previous reservation - draw_list.PrimReserve((cnt - prims_culled) * renderer.IdxConsumed, (cnt - prims_culled) * renderer.VtxConsumed); - prims_culled = 0; - } - } - else - { - if (prims_culled > 0) { - draw_list.PrimUnreserve(prims_culled * renderer.IdxConsumed, prims_culled * renderer.VtxConsumed); - prims_culled = 0; - } - cnt = ImMin(prims, (MaxIdx::Value - 0/*draw_list._VtxCurrentIdx*/) / renderer.VtxConsumed); - // reserve new draw command - draw_list.PrimReserve(cnt * renderer.IdxConsumed, cnt * renderer.VtxConsumed); - } - prims -= cnt; - for (unsigned int ie = idx + cnt; idx != ie; ++idx) { - if (!renderer.Render(draw_list, cull_rect, idx)) - prims_culled++; - } - } - if (prims_culled > 0) - draw_list.PrimUnreserve(prims_culled * renderer.IdxConsumed, prims_culled * renderer.VtxConsumed); -} - -template