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:
@@ -405,7 +405,7 @@ static void RenderRecentReceived(const AddressInfo& /* addr */,
|
||||
ImVec2(txX, rowPos.y + 2.0f * dp), OnSurfaceMedium(), typeText);
|
||||
|
||||
// Address (second line)
|
||||
float addrX = txX + S.drawElement("tabs.balance", "recent-tx-addr-offset").sizeOr(65.0f);
|
||||
float addrX = txX + S.drawElement("tabs.balance", "recent-tx-addr-offset").sizeOr(65.0f) * hs;
|
||||
std::string addrDisplay = util::truncateMiddle(tx.address,
|
||||
(int)S.drawElement("tabs.balance", "recent-tx-addr-trunc").sizeOr(20.0f));
|
||||
rowDL->AddText(capFont, capFont->LegacySize,
|
||||
@@ -424,7 +424,7 @@ static void RenderRecentReceived(const AddressInfo& /* addr */,
|
||||
std::string ago = recvTimeAgo(tx.timestamp);
|
||||
ImVec2 agoSz = capFont->CalcTextSizeA(capFont->LegacySize, 10000.0f, 0.0f, ago.c_str());
|
||||
rowDL->AddText(capFont, capFont->LegacySize,
|
||||
ImVec2(rightEdge - agoSz.x - S.drawElement("tabs.balance", "recent-tx-time-margin").sizeOr(4.0f),
|
||||
ImVec2(rightEdge - agoSz.x - S.drawElement("tabs.balance", "recent-tx-time-margin").sizeOr(4.0f) * hs,
|
||||
rowPos.y + 2.0f * dp),
|
||||
OnSurfaceDisabled(), ago.c_str());
|
||||
|
||||
@@ -488,6 +488,16 @@ void RenderReceiveTab(App* app)
|
||||
float groupStartY = ImGui::GetCursorPosY();
|
||||
float contentStartY = ImGui::GetCursorPosY();
|
||||
|
||||
// Reserve a slice of the available height for RECENT RECEIVED (ratio — mirrors
|
||||
// balance_tab's recent-tx-reserve). The main card's target height is capped so it can
|
||||
// never grow past (available - reserve): a no-op at 1.0x (mainCardTargetH already fits
|
||||
// well within scrollAvailH there), but at HiDPI it prevents the card — whose QR (280*dp)
|
||||
// and pads scale with dp while scrollAvailH is physical px — from eating the whole child
|
||||
// and evicting the list.
|
||||
float recvReserveRatio = S.drawElement("tabs.balance", "recent-tx-reserve-ratio").sizeOr(0.18f);
|
||||
float recvRecentReserve = std::max(0.0f, scrollAvailH) * recvReserveRatio;
|
||||
float recvCardCapH = std::max(0.0f, scrollAvailH - recvRecentReserve);
|
||||
|
||||
float formAvailW = ImGui::GetContentRegionAvail().x;
|
||||
float formW = formAvailW;
|
||||
ImGui::BeginGroup();
|
||||
@@ -603,7 +613,7 @@ void RenderReceiveTab(App* app)
|
||||
ImGui::Dummy(ImVec2(0, Layout::spacingSm()));
|
||||
|
||||
// Amount input with currency toggle
|
||||
float toggleW = S.drawElement("tabs.receive", "currency-toggle-width").size;
|
||||
float toggleW = S.drawElement("tabs.receive", "currency-toggle-width").size * Layout::dpiScale();
|
||||
float amtInputW = addrColW - toggleW - Layout::spacingMd();
|
||||
if (amtInputW < S.drawElement("tabs.receive", "amount-input-min-width").size) amtInputW = S.drawElement("tabs.receive", "amount-input-min-width").size;
|
||||
double usd_price = state.market.price_usd;
|
||||
@@ -667,8 +677,8 @@ void RenderReceiveTab(App* app)
|
||||
float bH = bMax.y - bMin.y;
|
||||
ImFont* font = ImGui::GetFont();
|
||||
ImVec2 textSz = font->CalcTextSizeA(font->LegacySize, 10000, 0, currLabel);
|
||||
float iconW = schema::UI().drawElement("tabs.receive", "currency-icon-width").size;
|
||||
float iconGap2 = schema::UI().drawElement("tabs.receive", "currency-icon-gap").size;
|
||||
float iconW = schema::UI().drawElement("tabs.receive", "currency-icon-width").size * Layout::dpiScale();
|
||||
float iconGap2 = schema::UI().drawElement("tabs.receive", "currency-icon-gap").size * Layout::dpiScale();
|
||||
float totalW2 = iconW + iconGap2 + textSz.x;
|
||||
float startX = bMin.x + ((bMax.x - bMin.x) - totalW2) * 0.5f;
|
||||
float cy = bMin.y + bH * 0.5f;
|
||||
@@ -866,7 +876,7 @@ void RenderReceiveTab(App* app)
|
||||
S.drawElement("tabs.receive", "action-btn-height").size * vScale);
|
||||
float footerH = innerGap + actionBtnH + pad;
|
||||
float currentCardH = ImGui::GetCursorScreenPos().y - containerMin.y;
|
||||
float targetCardH = Layout::mainCardTargetH(formW, vScale);
|
||||
float targetCardH = std::min(Layout::mainCardTargetH(formW, vScale), recvCardCapH);
|
||||
float footerTopH = targetCardH - footerH;
|
||||
if (currentCardH < footerTopH) {
|
||||
ImGui::Dummy(ImVec2(0, footerTopH - currentCardH));
|
||||
@@ -959,10 +969,11 @@ void RenderReceiveTab(App* app)
|
||||
ImGui::Dummy(ImVec2(0, pad));
|
||||
ImGui::Unindent(pad);
|
||||
|
||||
// Enforce shared card height (matches QR-driven target)
|
||||
// Enforce shared card height (matches QR-driven target), capped so the reserved
|
||||
// RECENT RECEIVED slice below stays on-screen at HiDPI.
|
||||
{
|
||||
float currentCardH = ImGui::GetCursorScreenPos().y - containerMin.y;
|
||||
float targetCardH = Layout::mainCardTargetH(formW, vScale);
|
||||
float targetCardH = std::min(Layout::mainCardTargetH(formW, vScale), recvCardCapH);
|
||||
if (currentCardH < targetCardH)
|
||||
ImGui::Dummy(ImVec2(0, targetCardH - currentCardH));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user