fix(keys): auto-width action buttons + content-fit key/address fields
Three layout fixes in the export-key modal, all symptoms of widths/heights authored as raw pixels while text scales with the user's font setting: - "Copy to Clipboard" no longer clips — the Show/Hide · Copy · QR buttons are auto-width (size 0) so they always fit their label; - those buttons now share one font, so Show/Hide matches Copy (was a smaller toggle-button font); - the read-only address and key fields are sized to the wrapped text instead of a fixed 60/80px, removing the empty space below their value. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -66,7 +66,6 @@ void KeyExportDialog::render(App* app)
|
||||
auto addrInput = S.input("dialogs.key-export", "address-input");
|
||||
auto revealBtn = S.button("dialogs.key-export", "reveal-button");
|
||||
auto keyDisplay = S.drawElement("dialogs.key-export", "key-display");
|
||||
auto toggleBtn = S.button("dialogs.key-export", "toggle-button");
|
||||
auto copyBtn = S.button("dialogs.key-export", "copy-button");
|
||||
auto closeBtn = S.button("dialogs.key-export", "close-button");
|
||||
|
||||
@@ -107,9 +106,14 @@ void KeyExportDialog::render(App* app)
|
||||
char addr_buf[512];
|
||||
strncpy(addr_buf, s_address.c_str(), sizeof(addr_buf) - 1);
|
||||
addr_buf[sizeof(addr_buf) - 1] = '\0';
|
||||
// Fit the field to the wrapped address (no excess empty space below it).
|
||||
(void)addrInput;
|
||||
const float addrFieldH =
|
||||
ImGui::CalcTextSize(addr_buf, nullptr, false,
|
||||
ImGui::GetContentRegionAvail().x - ImGui::GetStyle().FramePadding.x * 2.0f).y
|
||||
+ ImGui::GetStyle().FramePadding.y * 2.0f + 4.0f;
|
||||
ImGui::InputTextMultiline("##Address", addr_buf, sizeof(addr_buf),
|
||||
ImVec2(-1, (addrInput.height > 0 ? addrInput.height : 60) * Layout::dpiScale()),
|
||||
ImGuiInputTextFlags_ReadOnly);
|
||||
ImVec2(-1, addrFieldH), ImGuiInputTextFlags_ReadOnly);
|
||||
} else {
|
||||
char addr_buf[128];
|
||||
strncpy(addr_buf, s_address.c_str(), sizeof(addr_buf) - 1);
|
||||
@@ -199,34 +203,36 @@ void KeyExportDialog::render(App* app)
|
||||
} else {
|
||||
// Key has been fetched - display it
|
||||
|
||||
// Fit the field to the wrapped key (same length whether shown or masked).
|
||||
(void)keyDisplay;
|
||||
char key_buf[1024];
|
||||
if (s_show_key) {
|
||||
// Show the actual key
|
||||
char key_buf[1024];
|
||||
strncpy(key_buf, s_key.c_str(), sizeof(key_buf) - 1);
|
||||
key_buf[sizeof(key_buf) - 1] = '\0';
|
||||
ImGui::InputTextMultiline("##Key", key_buf, sizeof(key_buf),
|
||||
ImVec2(-1, (keyDisplay.height > 0 ? keyDisplay.height : 80) * Layout::dpiScale()), ImGuiInputTextFlags_ReadOnly);
|
||||
} else {
|
||||
// Show masked
|
||||
std::string masked(s_key.length(), '*');
|
||||
char masked_buf[1024];
|
||||
strncpy(masked_buf, masked.c_str(), sizeof(masked_buf) - 1);
|
||||
masked_buf[sizeof(masked_buf) - 1] = '\0';
|
||||
ImGui::InputTextMultiline("##Key", masked_buf, sizeof(masked_buf),
|
||||
ImVec2(-1, (keyDisplay.height > 0 ? keyDisplay.height : 80) * Layout::dpiScale()), ImGuiInputTextFlags_ReadOnly);
|
||||
strncpy(key_buf, masked.c_str(), sizeof(key_buf) - 1);
|
||||
}
|
||||
key_buf[sizeof(key_buf) - 1] = '\0';
|
||||
const float keyFieldH =
|
||||
ImGui::CalcTextSize(key_buf, nullptr, false,
|
||||
ImGui::GetContentRegionAvail().x - ImGui::GetStyle().FramePadding.x * 2.0f).y
|
||||
+ ImGui::GetStyle().FramePadding.y * 2.0f + 4.0f;
|
||||
ImGui::InputTextMultiline("##Key", key_buf, sizeof(key_buf),
|
||||
ImVec2(-1, keyFieldH), ImGuiInputTextFlags_ReadOnly);
|
||||
|
||||
// Action row: Show/Hide · Copy · QR
|
||||
// Action row: Show/Hide · Copy · QR. Auto-width buttons (size 0) so the label text never
|
||||
// clips at the user's font scale, and ONE shared font so they all match.
|
||||
ImGui::Spacing();
|
||||
ImFont* actionFont = S.resolveFont(copyBtn.font);
|
||||
|
||||
if (material::StyledButton(s_show_key ? TR("hide") : TR("show"), ImVec2(toggleBtn.width, 0), S.resolveFont(toggleBtn.font))) {
|
||||
if (material::StyledButton(s_show_key ? TR("hide") : TR("show"), ImVec2(0, 0), actionFont)) {
|
||||
s_show_key = !s_show_key;
|
||||
if (!s_show_key) s_show_qr = false; // hiding the key also hides its QR
|
||||
}
|
||||
|
||||
ImGui::SameLine();
|
||||
|
||||
if (material::StyledButton(TR("copy_to_clipboard"), ImVec2(copyBtn.width, 0), S.resolveFont(copyBtn.font))) {
|
||||
if (material::StyledButton(TR("copy_to_clipboard"), ImVec2(0, 0), actionFont)) {
|
||||
// Auto-clearing clipboard: the key (as sensitive as the seed) is wiped after ~45s.
|
||||
app->copySecretToClipboard(s_key);
|
||||
}
|
||||
@@ -234,8 +240,7 @@ void KeyExportDialog::render(App* app)
|
||||
// QR (only once revealed) — for scanning the key into another wallet.
|
||||
if (s_show_key) {
|
||||
ImGui::SameLine();
|
||||
if (material::StyledButton(s_show_qr ? TR("hide_qr") : TR("show_qr"),
|
||||
ImVec2(copyBtn.width, 0), S.resolveFont(copyBtn.font))) {
|
||||
if (material::StyledButton(s_show_qr ? TR("hide_qr") : TR("show_qr"), ImVec2(0, 0), actionFont)) {
|
||||
s_show_qr = !s_show_qr;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user