From e7a3f9010232b6cf867eb7825585ed339bca570b Mon Sep 17 00:00:00 2001 From: DanS Date: Thu, 9 Jul 2026 21:57:04 -0500 Subject: [PATCH] feat(ui): float all modals card-less like Manage Portfolio MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Drop the glass card + boxed title bar from every dialog so content floats directly on the blur backdrop under a plain h6 heading — the Manage-Portfolio look — unifying the whole modal system on one visual language (reverses the earlier card-for-small / float-for-large split). - Framework: the positional BeginOverlayDialog overload (used by all ~34 card dialogs) now defaults to floatingContent + plainHeading (draw_helpers.h). The 9 spec-form BlurFloat dialogs are unchanged; any dialog can still opt back to a card via an explicit OverlayStyle::GlassCard spec. Authored widths are kept (floating never resizes), so width-coupled layouts are unaffected. - Dedup: the framework h6 title made each dialog's own repeated title heading redundant. Removed the duplicate body heading from Import/Export key, Backup, daemon update, seed backup, seed migration, Defender-blocked (app.cpp), Wallets, and the send-confirm popup. - Close paths: dropping the title-bar close X is covered — every dialog has a footer button and/or the framework's outside-click dismiss (all pass p_open); send-confirm keeps Esc + Confirm/Cancel. Verified via the headless full UI sweep on dark + light: 17 modal surfaces float card-less with a single clean heading, nothing clipped, close controls present. Build clean, ctest passes. Co-Authored-By: Claude Opus 4.8 (1M context) --- src/app.cpp | 17 +---------------- src/ui/material/draw_helpers.h | 12 +++++++----- src/ui/windows/send_tab.cpp | 3 --- src/ui/windows/wallets_dialog.h | 2 -- 4 files changed, 8 insertions(+), 26 deletions(-) diff --git a/src/app.cpp b/src/app.cpp index 65b85eb..d14504f 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -2743,8 +2743,6 @@ void App::renderImportKeyDialog() return; } - ui::material::Type().text(ui::material::TypeStyle::H6, "Import Private Key"); - ImGui::Dummy(ImVec2(0, ui::Layout::spacingSm())); ImGui::TextWrapped("Enter a private key to import. The wallet will rescan the blockchain for transactions."); ImGui::Spacing(); @@ -2847,9 +2845,7 @@ void App::renderExportKeyDialog() return; } - ui::material::Type().text(ui::material::TypeStyle::H6, "Export Private Key"); - ImGui::Dummy(ImVec2(0, ui::Layout::spacingSm())); - ImGui::TextColored(ImVec4(0.9f, 0.4f, 0.4f, 1.0f), + ImGui::TextColored(ImVec4(0.9f, 0.4f, 0.4f, 1.0f), "WARNING: Anyone with this key can spend your coins!"); ImGui::Spacing(); @@ -2922,8 +2918,6 @@ void App::renderBackupDialog() return; } - ui::material::Type().text(ui::material::TypeStyle::H6, "Backup Wallet"); - ImGui::Dummy(ImVec2(0, ui::Layout::spacingSm())); ImGui::TextWrapped("Export all private keys to a file. Keep this file secure!"); ImGui::Spacing(); @@ -2998,8 +2992,6 @@ void App::renderDaemonUpdatePrompt() if (!ui::material::BeginOverlayDialog(TR("daemon_update_title"), &show_daemon_update_prompt_, 520.0f, 0.94f)) return; const float dp = ui::Layout::dpiScale(); - ui::material::Type().text(ui::material::TypeStyle::H6, TR("daemon_update_title")); - ImGui::Dummy(ImVec2(0, ui::Layout::spacingSm())); ImGui::TextWrapped("%s", TR("daemon_update_body")); ImGui::Spacing(); ImGui::PushStyleColor(ImGuiCol_Text, ui::material::OnSurfaceMedium()); @@ -3071,8 +3063,6 @@ void App::renderSeedBackupDialog() return; } - ui::material::Type().text(ui::material::TypeStyle::H6, TR("seed_backup_title")); - ImGui::Dummy(ImVec2(0, ui::Layout::spacingSm())); // Button widths are logical px; BeginOverlayDialog scales the card by dpiScale() so scale these // to match (raw widths render small/left-packed at higher DPI / font scale). const float dp = ui::Layout::dpiScale(); @@ -3158,8 +3148,6 @@ void App::renderSeedMigrationDialog() // BeginOverlayDialog scales the card by dpiScale(); the button widths below are authored in // logical px and must be scaled the same way or they render small/left-packed at higher DPI. const float dp = ui::Layout::dpiScale(); - ui::material::Type().text(ui::material::TypeStyle::H6, TR("mig_title")); - ImGui::Dummy(ImVec2(0, ui::Layout::spacingSm())); switch (seed_migration_step_) { case SeedMigrationStep::Intro: { @@ -3447,9 +3435,6 @@ void App::renderAntivirusHelpDialog() return; } - ui::material::Type().text(ui::material::TypeStyle::H6, "Windows Defender Blocked xmrig"); - ImGui::Dummy(ImVec2(0, ui::Layout::spacingSm())); - ImGui::TextWrapped( "Mining software is often flagged as potentially unwanted. " "Follow these steps to enable pool mining:"); diff --git a/src/ui/material/draw_helpers.h b/src/ui/material/draw_helpers.h index 154084f..464e413 100644 --- a/src/ui/material/draw_helpers.h +++ b/src/ui/material/draw_helpers.h @@ -1462,10 +1462,10 @@ inline bool BeginOverlayDialog(const OverlayDialogSpec& spec) return childVisible; } -// Positional overload — the default look for the app's dialogs: a card (auto-height, so small -// dialogs stay small) on the live-blur backdrop. The card renders opaque via the sole-consumer -// fallback (glass would thrash the single-slot blur cache against the radius-64 backdrop). A dialog -// that wants the old opaque scrim (no blur) can pass a spec with blurBackdrop = false. +// Positional overload — the default look for the app's dialogs: content floats directly on the +// live-blur backdrop (no glass card) under a plain h6 heading, matching the Manage-Portfolio +// editor. Auto-height keeps short dialogs short. A dialog that needs the old contained card can +// pass an explicit OverlayDialogSpec with style = OverlayStyle::GlassCard. inline bool BeginOverlayDialog(const char* title, bool* p_open, float cardWidth = 460.0f, float scrimOpacity = 0.92f, float cardBottomViewportRatio = 0.85f, const char* idSuffix = nullptr) @@ -1473,7 +1473,9 @@ inline bool BeginOverlayDialog(const char* title, bool* p_open, float cardWidth OverlayDialogSpec s; s.title = title; s.p_open = p_open; s.cardWidth = cardWidth; s.scrimOpacity = scrimOpacity; s.cardBottomViewportRatio = cardBottomViewportRatio; s.idSuffix = idSuffix; - s.blurBackdrop = true; + s.blurBackdrop = true; + s.floatingContent = true; // no glass card — content floats on the blur + s.plainHeading = true; // h6 heading instead of the boxed title bar (drops the ✕) return BeginOverlayDialog(s); } diff --git a/src/ui/windows/send_tab.cpp b/src/ui/windows/send_tab.cpp index 1f173ea..a6d0214 100644 --- a/src/ui/windows/send_tab.cpp +++ b/src/ui/windows/send_tab.cpp @@ -705,9 +705,6 @@ void RenderSendConfirmPopup(App* app) { float popW = ImGui::GetContentRegionAvail().x; ImDrawList* popDl = ImGui::GetWindowDrawList(); - Type().text(TypeStyle::H6, TR("confirm_transaction")); - ImGui::Dummy(ImVec2(0, Layout::spacingSm())); - float addrCardH = std::max(schema::UI().drawElement("tabs.send", "confirm-addr-card-min-height").size, schema::UI().drawElement("tabs.send", "confirm-addr-card-height").size * popVs); float popGlassRound = Layout::glassRounding() * S.drawElement("tabs.send", "confirm-glass-rounding-ratio").size; diff --git a/src/ui/windows/wallets_dialog.h b/src/ui/windows/wallets_dialog.h index 42a8d16..ec55991 100644 --- a/src/ui/windows/wallets_dialog.h +++ b/src/ui/windows/wallets_dialog.h @@ -52,8 +52,6 @@ public: if (s_needScan) { scan(); s_needScan = false; } if (BeginOverlayDialog(TR("wallets_title"), &s_open, 780.0f, 0.94f)) { - Type().text(TypeStyle::H6, TR("wallets_title")); - ImGui::Dummy(ImVec2(0, Layout::spacingXs())); Type().textColored(TypeStyle::Caption, OnSurfaceMedium(), TR("wallets_intro")); ImGui::Dummy(ImVec2(0, Layout::spacingSm()));