fix(send/receive): unify card width, justify receive footer, fix recipient-row button height/clip/glyph
Send and Receive are now consistent in layout, and the Send recipient row's buttons
render correctly.
Card envelope (Send ⇄ Receive consistency):
- Add Layout::mainComposeCardBox(availW) — a single shared source for the compose card's
width + centering (fill the available column up to content-max-width, then center). Both
tabs derive their card from it, so they can't drift again. Previously Send capped at
760dp and Receive at 860dp, so the Send card rendered ~150px narrower on any window wider
than ~860dp; now they fill available width identically.
Receive:
- Justify the footer buttons edge-to-edge (equal shares over the live count) instead of
left-clustering with dead space, matching Send's full-width footer rhythm.
- Build the address-dropdown preview to the combo's real pixel width so the trailing
balance ("— 12.00000000 DRGX") no longer hard-clips at 150% (was char-count truncation).
Send recipient row (input | Paste | contacts-icon):
- Pin the contacts icon button to the frame height so the larger iconMed font doesn't
auto-size it taller than Paste/the input.
- Reserve the real ItemSpacing.x gaps (not the smaller spacingSm token) so the row no
longer overshoots the card and clips the icon's right border.
draw_helpers (root cause, app-wide):
- TactileButton's icon path measured/drew the label INCLUDING the "##id" suffix (which
CalcTextSizeA/AddText don't strip the way ImGui's text render does), shoving the glyph
off-center-left. Strip at "##" before measuring/drawing. Corrects any icon button that
passes an explicit size and a "##id" label; no-op for labels without "##".
Verified via headless sweeps at 1.0x and 1.5x, plus a real 3800px-wide render (both cards
byte-identical at L=1174/R=2773). ctest 1/1.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -1272,12 +1272,13 @@ 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);
|
||||
// Fill the available column up to the content-max-width cap, then center. Shared with the
|
||||
// Receive tab via mainComposeCardBox() so the two card envelopes are identical in width and
|
||||
// position (Send previously capped at 760dp vs Receive's 860dp, so Send rendered narrower).
|
||||
// The recent-sends list below deliberately keeps the full column width (formAvailW).
|
||||
Layout::CardBox formBox = Layout::mainComposeCardBox(formAvailW);
|
||||
float formCardW = formBox.width;
|
||||
float formOffsetX = formBox.offsetX;
|
||||
float formW = formAvailW;
|
||||
ImGui::BeginGroup();
|
||||
|
||||
@@ -1367,7 +1368,10 @@ void RenderSendTab(App* app)
|
||||
|
||||
float pasteW = std::max(schema::UI().drawElement("tabs.send", "paste-btn-min-width").size, colW * schema::UI().drawElement("tabs.send", "paste-btn-width-ratio").size);
|
||||
float contactsW = ImGui::GetFrameHeight(); // compact square icon button for the contact picker
|
||||
ImGui::PushItemWidth(colW - pasteW - contactsW - Layout::spacingSm() * 2.0f);
|
||||
// Reserve the TWO real SameLine gaps (each = ItemSpacing.x) between input|Paste|icon.
|
||||
// Reserving spacingSm (a smaller token) under-counted the gap, so the row overshot colW by
|
||||
// ~2*(ItemSpacing.x - spacingSm) and the icon's right border clipped past the card edge.
|
||||
ImGui::PushItemWidth(colW - pasteW - contactsW - ImGui::GetStyle().ItemSpacing.x * 2.0f);
|
||||
|
||||
// Show clipboard preview as transparent overlay when paste button is hovered
|
||||
bool paste_hovered = false;
|
||||
@@ -1425,9 +1429,12 @@ void RenderSendTab(App* app)
|
||||
}
|
||||
}
|
||||
|
||||
// Contact picker — pick a saved contact's address as the recipient.
|
||||
// Contact picker — pick a saved contact's address as the recipient. Pin the height to the
|
||||
// frame height (== the input + Paste height) so the larger iconMed font doesn't auto-size
|
||||
// this square button taller than its row-mates. (Passing a non-zero size also routes
|
||||
// TactileButton through its precise InvisibleButton + centered-glyph path.)
|
||||
ImGui::SameLine();
|
||||
if (material::TactileButton(ICON_MD_CONTACTS "##pickContact", ImVec2(contactsW, 0),
|
||||
if (material::TactileButton(ICON_MD_CONTACTS "##pickContact", ImVec2(contactsW, ImGui::GetFrameHeight()),
|
||||
material::Type().iconMed()))
|
||||
ImGui::OpenPopup("##ContactPickerPopup");
|
||||
if (ImGui::IsItemHovered()) material::Tooltip("%s", TR("send_contacts_button"));
|
||||
|
||||
Reference in New Issue
Block a user