From 027a7ba3eb19ec05e0f086997929b69cad6b1a0d Mon Sep 17 00:00:00 2001 From: ocornut Date: Mon, 6 Dec 2021 16:20:53 +0100 Subject: [PATCH] Clipper: use line size instead of cursor comparaison when range are large. (#3609, #3962 + https://github.com/ocornut/imgui_club/issues/20) --- imgui.cpp | 6 ++++++ imgui.h | 2 +- imgui_internal.h | 1 + 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/imgui.cpp b/imgui.cpp index 722e84b4..d5cf247e 100644 --- a/imgui.cpp +++ b/imgui.cpp @@ -2471,17 +2471,23 @@ bool ImGuiListClipper::Step() if (ItemsHeight <= 0.0f) { IM_ASSERT(data->StepNo == 1); + bool affected_by_floating_point_precision = false; if (table) { const float pos_y1 = table->RowPosY1; // Using RowPosY1 instead of StartPosY to handle clipper straddling the frozen row const float pos_y2 = table->RowPosY2; // Using RowPosY2 instead of CursorPos.y to take account of tallest cell. ItemsHeight = pos_y2 - pos_y1; window->DC.CursorPos.y = pos_y2; + affected_by_floating_point_precision = ImIsFloatAboveGuaranteedIntegerPrecision(pos_y1) || ImIsFloatAboveGuaranteedIntegerPrecision(pos_y2); } else { ItemsHeight = (window->DC.CursorPos.y - StartPosY) / (float)(DisplayEnd - DisplayStart); + affected_by_floating_point_precision = ImIsFloatAboveGuaranteedIntegerPrecision(StartPosY) || ImIsFloatAboveGuaranteedIntegerPrecision(window->DC.CursorPos.y); } + if (affected_by_floating_point_precision) + ItemsHeight = window->DC.PrevLineSize.y + g.Style.ItemSpacing.y; // FIXME: Technically wouldn't allow multi-line entries. + IM_ASSERT(ItemsHeight > 0.0f && "Unable to calculate item height! First item hasn't moved the cursor vertically!"); calc_clipping = true; // If item height had to be calculated, calculate clipping afterwards. } diff --git a/imgui.h b/imgui.h index d2da5fed..215106ea 100644 --- a/imgui.h +++ b/imgui.h @@ -64,7 +64,7 @@ Index of this file: // Version // (Integer encoded as XYYZZ for use in #if preprocessor conditionals. Work in progress versions typically starts at XYY99 then bounce up to XYY00, XYY01 etc. when release tagging happens) #define IMGUI_VERSION "1.86 WIP" -#define IMGUI_VERSION_NUM 18515 +#define IMGUI_VERSION_NUM 18516 #define IMGUI_CHECKVERSION() ImGui::DebugCheckVersionAndDataLayout(IMGUI_VERSION, sizeof(ImGuiIO), sizeof(ImGuiStyle), sizeof(ImVec2), sizeof(ImVec4), sizeof(ImDrawVert), sizeof(ImDrawIdx)) #define IMGUI_HAS_TABLE diff --git a/imgui_internal.h b/imgui_internal.h index b5d49049..d56204d3 100644 --- a/imgui_internal.h +++ b/imgui_internal.h @@ -448,6 +448,7 @@ static inline float ImDot(const ImVec2& a, const ImVec2& b) static inline ImVec2 ImRotate(const ImVec2& v, float cos_a, float sin_a) { return ImVec2(v.x * cos_a - v.y * sin_a, v.x * sin_a + v.y * cos_a); } static inline float ImLinearSweep(float current, float target, float speed) { if (current < target) return ImMin(current + speed, target); if (current > target) return ImMax(current - speed, target); return current; } static inline ImVec2 ImMul(const ImVec2& lhs, const ImVec2& rhs) { return ImVec2(lhs.x * rhs.x, lhs.y * rhs.y); } +static inline bool ImIsFloatAboveGuaranteedIntegerPrecision(float f) { return f <= -16777216 || f >= 16777216; } IM_MSVC_RUNTIME_CHECKS_RESTORE // Helpers: Geometry