From f8fbc32463b385b2e12447a2174985675349a460 Mon Sep 17 00:00:00 2001 From: DanS Date: Fri, 10 Jul 2026 14:26:40 -0500 Subject: [PATCH] fix(wallets): folder picker fills the window; footer no longer clipped The picker used a fixed-height card whose budget under-counted ImGui's inter-item spacing, so on larger windows / at 150% DPI the footer buttons overflowed the card's clip rect and got cut off. Rework it as a flex column: the card takes ~82% of the viewport height (like the console command-reference modal) and the directory list fills whatever space is left above a reserved footer block. The status line + Scan/Cancel buttons are now always pinned at the bottom and visible at any window size or DPI, and the browsing area is generous instead of a cramped fixed row count. Verified headless at 100% + 150%. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/ui/windows/folder_picker.h | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/ui/windows/folder_picker.h b/src/ui/windows/folder_picker.h index b4b3c94..c44307a 100644 --- a/src/ui/windows/folder_picker.h +++ b/src/ui/windows/folder_picker.h @@ -63,25 +63,20 @@ public: ImFont* icoFont = Type().iconSmall(); ImFont* metaFont = Type().caption(); - // ---- Fixed-height card sized to a stable row budget (no auto-height feedback) ---------- - const int kVisRows = 9; - const float rowH = rowFont->LegacySize + Layout::spacingMd(); + const float rowH = rowFont->LegacySize + Layout::spacingMd(); const float listPad = Layout::spacingXs(); - const float listH = kVisRows * rowH + listPad * 2.0f; - const float headH = Type().h6()->LegacySize + Layout::spacingXs(); - const float pathH = ImGui::GetFrameHeight() + Layout::spacingSm(); - const float statusH = metaFont->LegacySize + Layout::spacingXs(); - const float footH = Layout::spacingSm() + 1.0f + Layout::spacingSm() - + ImGui::GetFrameHeightWithSpacing(); - const float padV = 52.0f; - const float cardH = (headH + pathH + listH + statusH + footH + padV) / dp; + // The card takes a generous share of the window (a file browser wants room) — not a fixed + // row count. The list inside FLEXES to fill whatever height is left above the footer, so the + // footer is always pinned + visible and nothing clips, at any window size or DPI. + const float vpH = ImGui::GetMainViewport()->Size.y; + const float cardH = (vpH * 0.82f) / dp; // logical; the framework re-applies dp + caps at vp-32 OverlayDialogSpec ov; ov.title = TR("picker_title"); ov.p_open = &s_open; ov.style = OverlayStyle::BlurFloat; - ov.cardWidth = 720.0f; + ov.cardWidth = 760.0f; ov.cardHeight = cardH; ov.idSuffix = "folderpicker"; if (!BeginOverlayDialog(ov)) return; @@ -145,6 +140,15 @@ public: ImGui::Dummy(ImVec2(0, Layout::spacingSm())); // ---- Directory list: folders (clickable) then *.dat wallets present (informational) ---- + // Flex: the list fills the space between the path bar and the footer block. Reserving a + // (slightly generous) footer height keeps the status line + buttons pinned and never clipped. + const ImGuiStyle& gstyle = ImGui::GetStyle(); + const float footerBlockH = Layout::spacingXs() + metaFont->LegacySize // status line + + Layout::spacingSm() + 1.0f + Layout::spacingSm() // separator block + + ImGui::GetFrameHeight() // footer buttons + + 6.0f * gstyle.ItemSpacing.y; // inter-item gaps + float listH = ImGui::GetContentRegionAvail().y - footerBlockH; + listH = std::max(listH, rowH * 3.0f + listPad * 2.0f); ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(listPad, listPad)); ImGui::PushStyleColor(ImGuiCol_ChildBg, WithAlpha(OnSurface(), 20)); ImGui::BeginChild("##pickerList", ImVec2(fullW, listH), true);