feat(material): extract DialogActionFooter + GlassSectionScope helpers

Phase 0b of the settings-modal redesign — pull the reference dialog's two
repeated patterns into shared helpers so the upcoming migrations are mechanical
and identical:

- material::DialogActionFooter(primary, enabled, close, &outPrimary, &outClose)
  — the centered fixed-width primary+Close TactileButton pair with no divider.
- material::GlassSectionScope — an RAII auto-sized glass sub-section using a LOCAL
  ImDrawListSplitter (combo-safe, unlike GlassCardScope's shared ChannelsSplit) with
  the reference's 12/10 padding and 8dp rounding; interiorWidth() for full-width kids.

Dogfooded by refactoring renderImportKeyDialog's footer and scan-height panel onto
them — same padding/spec/centering, so the render is unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-13 20:49:04 -05:00
parent 2b191cea34
commit 8b9cd5bf80
2 changed files with 72 additions and 36 deletions

View File

@@ -3049,20 +3049,9 @@ void App::renderImportKeyDialog()
sodium_memzero(import_key_scan_height_, sizeof(import_key_scan_height_)); // no stale height
const int tip = state_.sync.blocks; // chain tip = slider max; 0 when unknown
// Render the content on an upper draw channel, then paint the glass panel behind it once the
// block's height is known (immediate-mode auto-sized panel via a draw-list splitter).
ImDrawList* dl = ImGui::GetWindowDrawList();
ImDrawListSplitter splitter;
splitter.Split(dl, 2);
splitter.SetCurrentChannel(dl, 1);
const float padX = 12.0f * dp, padY = 10.0f * dp;
const float panelW = ImGui::GetContentRegionAvail().x;
const ImVec2 panelMin = ImGui::GetCursorScreenPos();
ImGui::Dummy(ImVec2(0, padY));
ImGui::Indent(padX);
const float availW = ImGui::GetContentRegionAvail().x - padX; // interior width (both side paddings)
// Auto-sized glass sub-section (combo-safe local splitter; see GlassSectionScope).
m::GlassSectionScope section;
const float availW = section.interiorWidth();
// Label + current chain height, right-aligned within the interior.
const float rowStartX = ImGui::GetCursorPosX();
@@ -3083,18 +3072,6 @@ void App::renderImportKeyDialog()
// start" hint was dropped as self-evident (0 is the field's default).
if (transparentKey)
ImGui::TextColored(ImGui::ColorConvertU32ToFloat4(m::OnSurfaceDisabled()), "%s", TR("import_scan_transparent"));
ImGui::Unindent(padX);
ImGui::Dummy(ImVec2(0, padY));
const ImVec2 panelMax(panelMin.x + panelW, ImGui::GetCursorScreenPos().y);
splitter.SetCurrentChannel(dl, 0);
m::GlassPanelSpec spec;
spec.rounding = 8.0f * dp;
spec.fillAlpha = 20;
spec.borderAlpha = 30;
m::DrawGlassPanel(dl, panelMin, panelMax, spec);
splitter.Merge(dl);
}
ImGui::Dummy(ImVec2(0, 2.0f * dp));
@@ -3147,17 +3124,15 @@ void App::renderImportKeyDialog()
ImGui::Spacing();
float btnW = 130.0f * dp;
const bool running = sweepMode ? sweepRunning : import_in_progress_;
// Sweep needs a spending key AND a destination (a picked address when not using a fresh one).
const bool destReady = !sweepMode || sweep_dest_mode_ == 0 || sweep_dest_pick_[0] != '\0';
const bool canAct = recognized && state_.connected && !running && destReady;
// Center the action + Close buttons in the (wider) dialog.
const float footTotal = btnW * 2.0f + ImGui::GetStyle().ItemSpacing.x;
const float footOff = (ImGui::GetContentRegionAvail().x - footTotal) * 0.5f;
if (footOff > 0.0f) ImGui::SetCursorPosX(ImGui::GetCursorPosX() + footOff);
ImGui::BeginDisabled(!canAct);
if (m::TactileButton(sweepMode ? TR("sweep_button") : TR("import_key_import"), ImVec2(btnW, 0))) {
bool doAction = false, doClose = false;
m::DialogActionFooter(sweepMode ? TR("sweep_button") : TR("import_key_import"), canAct,
TR("close"), doAction, doClose);
if (doClose) show_import_key_ = false;
if (doAction) {
int startHeight = 0; // 0 = full rescan. Shielded imports (z_importkey) honor it; transparent
if (import_key_scan_height_[0]) { // WIF (importprivkey) ignores it.
startHeight = std::atoi(import_key_scan_height_);
@@ -3187,9 +3162,6 @@ void App::renderImportKeyDialog()
});
}
}
ImGui::EndDisabled();
ImGui::SameLine();
if (m::TactileButton(TR("close"), ImVec2(btnW, 0))) show_import_key_ = false;
// Wipe the key the moment the dialog closes (Close button OR outside-click, which clears
// show_import_key_ mid-frame). in_progress is left to the callback to clear.