perf(overview): clip the address list to the visible rows
The Overview address list built all N rows on every frame (icons, labels, balances, buttons, an InvisibleButton and a context-menu check per address) and allocated a vector of N row positions, however few rows fit on screen; the edge mask then walked all their vertices. An ImGuiListClipper now submits only the rows that intersect the list's clip rect, plus: - one guard row on each side, so dividers and anti-aliased edges at the clip boundary are drawn as before; - the row being dragged and the row whose context menu is open, so drag-to-reorder and the menu keep working when they scroll away; - the rows keyboard navigation targets (kept by the clipper itself). Before each row the cursor is put back exactly where the unclipped loop left it, so the density-scaled spacing, which depends on the cursor position, and every row's geometry are unchanged. Row tops are computed from the index, so the per-frame vector is gone, and the scroll extent is the same. The row model (sort, filter) is still rebuilt over all addresses each frame. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
@@ -2,6 +2,7 @@
|
||||
|
||||
#include <algorithm>
|
||||
#include <cctype>
|
||||
#include <cmath>
|
||||
#include <cstdio>
|
||||
|
||||
namespace dragonx {
|
||||
@@ -106,5 +107,26 @@ std::string FormatAddressUsdValue(double balance, double priceUsd)
|
||||
return buffer;
|
||||
}
|
||||
|
||||
AddressRowWindow ComputeAddressRowWindow(float clipMinY, float clipMaxY, float startY, float rowH, int rowCount)
|
||||
{
|
||||
AddressRowWindow w;
|
||||
if (rowCount <= 0) return w;
|
||||
w.end = rowCount; // fail open (every row) on degenerate input
|
||||
if (!(rowH > 0.0f)) return w;
|
||||
const double first = std::floor(((double)clipMinY - startY) / rowH) - 1.0;
|
||||
const double last = std::ceil(((double)clipMaxY - startY) / rowH) + 1.0; // exclusive
|
||||
if (!std::isfinite(first) || !std::isfinite(last)) return w;
|
||||
w.begin = (int)std::clamp(first, 0.0, (double)rowCount);
|
||||
w.end = (int)std::clamp(last, (double)w.begin, (double)rowCount);
|
||||
return w;
|
||||
}
|
||||
|
||||
float AddressRowEntryCursorY(int i, float startY, float rowH, float itemSpacingY)
|
||||
{
|
||||
if (i <= 0) return startY;
|
||||
const float prevTop = startY + (i - 1) * rowH; // the row loop's row-top expression
|
||||
return (float)(int)(prevTop + rowH + itemSpacingY); // ImGui::ItemSize: IM_TRUNC(line_y1 + line_height + ItemSpacing.y)
|
||||
}
|
||||
|
||||
} // namespace ui
|
||||
} // namespace dragonx
|
||||
|
||||
Reference in New Issue
Block a user