fix(ui): finish HiDPI pass — cosmetic ×dpiScale, narrow-width reflow, recent-list reserves

The tail of the DPI/font-scale/responsiveness audit — ~26 remaining findings.

Container / recent-list (Theme-1 leftovers):
- Send: drop NoScrollbar|NoScrollWithMouse on ##SendFormScroll so Recent Sends is
  reachable at font_scale 1.5 (parity with receive).
- Receive: cap the QR/form card via std::min(mainCardTargetH, availH - recentReserve)
  so RECENT RECEIVED stays on-screen (identity at 1.0x).
- Wallets dialog: size the capped-mode list to whole rows so it no longer clips a
  partial row / crowds "Create a new wallet".

Narrow-width (1024px) reflow:
- Console toolbar reserves space for ALL trailing controls (both icon toggles + zoom
  buttons) so the +/- zoom no longer runs off-window.
- History sort combo sized to its measured widest localized label ("Newest first").
- Settings Theme/Layout/Language row: scale the wide→stacked breakpoint by dpiScale so
  it drops to full-width stacked combos at 1.5x (Consolidated Card no longer clips).
- Recent-tx type label: derive the address column X from the measured label width so it
  can't collide at narrow widths.
- Mining Recent Pool Payouts: floor the panel height to fit the empty-state caption.

Cosmetic ×dpiScale() on absolute geometry (no-ops at 1.0x): mining SOLO|POOL toggle &
idle combos, market pair-chips, password/PIN strength bars, receive/send currency
toggles, explorer search bar/rows/rounding, About-card logo, chat empty-state wrap,
recent-list address/time offsets, address-toolbar & two-row action buttons, console
line-gap/status-dot/pane rounding.

Verified at font_scale 1.5 and at 1024px across full-node + Lite + Windows (ctest
green) and an adversarial diff review (one over-reserve regression fixed).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-08-18 21:29:10 -05:00
co-authored by Claude Opus 4.8
parent 99d1e73676
commit ce8c7696d4
15 changed files with 118 additions and 54 deletions
+7 -7
View File
@@ -446,10 +446,10 @@ static void renderSearchBar(App* app, float availWidth) {
float navW = navBtnSz * 2.0f + pageW + navGap * 2.0f;
float inputW = std::min(
S.drawElement("tabs.explorer", "search-input-width").size,
S.drawElement("tabs.explorer", "search-input-width").size * Layout::dpiScale(),
availWidth * 0.65f);
float btnW = S.drawElement("tabs.explorer", "search-button-width").size;
float barH = S.drawElement("tabs.explorer", "search-bar-height").size;
float btnW = S.drawElement("tabs.explorer", "search-button-width").size * Layout::dpiScale();
float barH = S.drawElement("tabs.explorer", "search-bar-height").size * Layout::dpiScale();
// Clamp so search bar never overflows
float maxInputW = availWidth - btnW - navW - pad * 4 - Type().iconMed()->LegacySize;
@@ -755,8 +755,8 @@ static void renderRecentBlocks(App* app, float availWidth) {
ImFont* body2 = Type().body2();
ImFont* sub1 = Type().subtitle1();
float baseRowH = S.drawElement("tabs.explorer", "row-height").size;
float rowRound = S.drawElement("tabs.explorer", "row-rounding").size;
float baseRowH = S.drawElement("tabs.explorer", "row-height").size * dp;
float rowRound = S.drawElement("tabs.explorer", "row-rounding").size * dp;
float headerH = ovFont->LegacySize + Layout::spacingSm() + pad * 0.5f;
// Stretch card to fill the remaining tab height; rows scroll inside.
@@ -989,7 +989,7 @@ static void renderRecentBlocks(App* app, float availWidth) {
ImGui::EndChild();
float fadeZone = S.drawElement("tabs.explorer", "scroll-fade-zone").size;
float fadeZone = S.drawElement("tabs.explorer", "scroll-fade-zone").size * dp;
ApplyScrollEdgeMask(dl, parentVtx, childDL, childVtx,
rowAreaTop, rowAreaTop + rowAreaH, fadeZone, scrollY, scrollMaxY);
@@ -1179,7 +1179,7 @@ static void renderBlockDetailModal(App* app) {
ImGui::Spacing();
float txRowH = S.drawElement("tabs.explorer", "tx-row-height").size;
float txRowH = S.drawElement("tabs.explorer", "tx-row-height").size * dp;
ImU32 linkCol = schema::UI().resolveColor("var(--secondary-light)");
for (int i = 0; i < (int)s_detail_txids.size(); i++) {