feat(market): migrate portfolio modal onto the shared blur-overlay framework (Phase 1)

Dogfood the Phase 0 framework: RenderPortfolioEditor now opens via
material::BeginOverlayDialog(BlurFloat) + EndOverlayDialog instead of its own
inline overlay scaffold, and uses the promoted material:: SegmentedControl /
RightAlignX / BeginFadeScrollChild helpers (overlay_scroll.h). Delete the
portfolio's inline backdrop/capture-once state machine + its PfEditState capture
statics + the four local helper copies. App::render's ModalRenderGuard is now
driven by the modal-agnostic AnyBlurOverlayActiveLastFrame() (timing-equivalent),
and LatchBlurOverlayActive() at frame end handles the acrylic re-capture on close.

Framework tweak: floating cards pop the card WindowPadding after BeginChild (so
nested children don't inherit it) and center button labels, keeping the net
style-var count at 2 so EndOverlayDialog is unchanged and GlassCard stays
byte-identical. RenderPortfolioEditor: 357 -> 282 lines. Needs GUI verification
that the portfolio modal is visually/behaviourally unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-07-04 02:33:15 -05:00
parent d91be3b34e
commit ebf01bd858
3 changed files with 40 additions and 195 deletions

View File

@@ -1243,11 +1243,12 @@ void App::render()
// Process deferred encryption from wizard (runs in background)
processDeferredEncryption();
// While the full-window portfolio modal is open: (1) suppress panel theme-effects for the whole
// While any full-window BLUR overlay is open: (1) suppress panel theme-effects for the whole
// frame so their foreground-draw-list borders (sidebar included) don't bleed over the overlay;
// (2) mark a full-window blur overlay active so glass panels use their opaque fallback (they're
// covered by the overlay backdrop, and this leaves the backdrop as the sole acrylic blur caller).
// RAII-restored to the prior state on any return path.
// Driven by the shared framework's last-frame latch (modal-agnostic; timing-equivalent to the old
// PortfolioEditorActive() signal). RAII-restored to the prior state on any return path.
struct ModalRenderGuard {
bool fxOn, wasEffects;
explicit ModalRenderGuard(bool modalOpen) {
@@ -1260,7 +1261,7 @@ void App::render()
if (fxOn) ui::effects::ThemeEffects::instance().setEnabled(true);
ui::material::SetFullWindowBlurOverlayActive(false);
}
} modalGuard(ui::PortfolioEditorActive());
} modalGuard(ui::material::AnyBlurOverlayActiveLastFrame());
// Main content area - use full window (no menu bar)
ImGuiViewport* viewport = ImGui::GetMainViewport();
@@ -1913,6 +1914,10 @@ void App::render()
// Render notifications (toast messages)
ui::Notifications::instance().render();
// Latch whether any blur overlay was drawn this frame (for next frame's ModalRenderGuard) and, on
// the overlay's close transition, invalidate the acrylic capture so glass panels re-blur cleanly.
ui::material::LatchBlurOverlayActive();
}
void App::renderStatusBar()