feat(ui): width-responsiveness — content max-width cap + per-surface form/input clamps
Wide/ultrawide (1440-3440px) responsiveness was unhealthy: no page/content-level max-width cap existed, and every card/form/table derived width from raw GetContentRegionAvail().x with floor-only clamps, so surfaces stretched edge-to-edge (2000-3000px inputs, ballooning cards, giant grid cells, 2000px+ dead row-voids). Root cause: adopt the (previously dead-code) clamp helpers. - New Layout::kContentMaxWidth() (~1600dp, tunable via ui.toml [layout] content-max-width; <=0 disables). Cap ##ContentArea to it and center the column in wider windows — every tab derives from this child, so one change tames the app at wide widths. No-op below the cap (fills as before), so 1080p/1440p are unaffected. Per-surface upper-clamps (std::min(cap*dp, expr), floors preserved) where a single element is still too wide even within the capped column: - Settings: Theme/Layout/Language combos, the font-scale slider (~3000px -> 360dp), the effect sliders, Explorer URL and RPC credential fields. - Send / Receive: cap the compose / receive cards to a readable form width and center them (Indent(pad+offset) so the auto-layout fields align with the hand-drawn card); the recent-tx lists below keep the full column width. - Chat message bubbles + composer, mining pool URL/payout inputs + stats left/right split, contacts search, and the lite-network add-server row / server cards / status panel (capped + centered). - Wizard: vertically center the cards when they fit (was top-anchored, leaving a void on tall monitors), compensating the content-height measurement so it can't oscillate. The 1600 cap also subsumes the fixed-4-column balance grids (~400px cards) and the right-anchored row dead-gaps (voids shrink from ~2700px to ~800px), so those are left to the cap rather than blind column/row redesigns. Verified at 1024/1280 (and via a temporary 900dp cap to exercise the cap+center path, since the test display clamps to 1280) across full-node + Lite + Windows (ctest green) and an adversarial diff review (clean). The true wide/ultrawide look and the 1600dp cap value still want eyes on a real wide monitor. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1266,6 +1266,12 @@ void RenderSendTab(App* app)
|
||||
float contentStartY = ImGui::GetCursorPosY();
|
||||
|
||||
float formAvailW = ImGui::GetContentRegionAvail().x;
|
||||
// The compose form reads best as a centered fixed-width column, not edge-to-edge.
|
||||
// Cap the card to a readable form width and center it; the recent-sends list below
|
||||
// deliberately keeps the full column width (formAvailW).
|
||||
const float sendDp = Layout::dpiScale();
|
||||
float formCardW = std::min(formAvailW, 760.0f * sendDp);
|
||||
float formOffsetX = std::max(0.0f, (formAvailW - formCardW) * 0.5f);
|
||||
float formW = formAvailW;
|
||||
ImGui::BeginGroup();
|
||||
|
||||
@@ -1280,7 +1286,15 @@ void RenderSendTab(App* app)
|
||||
// ================================================================
|
||||
// COMPOSE FORM — single container for all fields
|
||||
// ================================================================
|
||||
// Full-column left edge, restored after the centered card so the recent-sends
|
||||
// list below spans the full width again.
|
||||
float formLeftX = ImGui::GetCursorPosX();
|
||||
{
|
||||
// Center the capped compose card: offset the cursor by the leftover half-margin,
|
||||
// then derive every field/divider/button from the card width (not the full column).
|
||||
float formW = formCardW;
|
||||
if (formOffsetX > 0.0f)
|
||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + formOffsetX);
|
||||
ImVec2 containerMin = ImGui::GetCursorScreenPos();
|
||||
float pad = Layout::spacingLg();
|
||||
float innerW = formW - pad * 2;
|
||||
@@ -1293,8 +1307,10 @@ void RenderSendTab(App* app)
|
||||
dl->ChannelsSplit(2);
|
||||
dl->ChannelsSetCurrent(1);
|
||||
|
||||
// Indent content by pad so every line is inset from the card edges
|
||||
ImGui::Indent(pad);
|
||||
// Indent content by pad so every line is inset from the card edges. Fold in formOffsetX so the
|
||||
// auto-layout fields land inside the centered card (Indent() positions from the window's left, so
|
||||
// without this the fields would sit at the un-offset column while the glass card is centered).
|
||||
ImGui::Indent(pad + formOffsetX);
|
||||
ImGui::Dummy(ImVec2(0, pad * vScale)); // top padding
|
||||
|
||||
// ---- SOURCE ADDRESS ----
|
||||
@@ -1593,7 +1609,7 @@ void RenderSendTab(App* app)
|
||||
|
||||
// Add bottom padding
|
||||
ImGui::Dummy(ImVec2(0, pad * vScale));
|
||||
ImGui::Unindent(pad);
|
||||
ImGui::Unindent(pad + formOffsetX);
|
||||
|
||||
// Enforce shared card height (matches receive tab)
|
||||
{
|
||||
@@ -1626,7 +1642,8 @@ void RenderSendTab(App* app)
|
||||
}
|
||||
}
|
||||
|
||||
// ---- RECENT SENDS ----
|
||||
// ---- RECENT SENDS ---- (full column width; reset X off the centered card)
|
||||
ImGui::SetCursorPosX(formLeftX);
|
||||
RenderRecentSends(state, formW, capFont, app);
|
||||
|
||||
ImGui::EndGroup();
|
||||
|
||||
Reference in New Issue
Block a user