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) <noreply@anthropic.com>
This commit is contained in:
2026-07-10 14:26:40 -05:00
parent 06c8b99bce
commit f8fbc32463

View File

@@ -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);