The acrylic system only blurred a frozen snapshot of the static app background. Add an overlay-time re-capture so the Manage-portfolio modal blurs the LIVE tab content behind it. - AcrylicMaterial::captureLiveFramebuffer() (GL blit of FB 0 / DX11 CopyResource of the backbuffer + no-backend stub) mirrors captureBackgroundDirect but bypasses the dirtyFrames_ gate so it refreshes every frame the overlay is open, forcing a re-blur. - ImGuiAcrylic::GetLiveCaptureCallback() returns a draw callback for it. - market_tab: the modal inserts that callback (+ ImDrawCallback_ResetRenderState) at the START of its overlay draw list, before the backdrop, so the capture holds the app UI drawn below and the backdrop blurs it. On close, InvalidateCapture() re-captures the background so other glass panels don't keep blurring the stale live capture. - Panel theme-effects are suppressed during the market render while the modal is open (their foreground-draw-list borders draw above all windows and would otherwise bleed over the overlay). Market tab body is rendered again (no longer skipped). - Backdrop draws the acrylic at full strength (fallbackColor.w=1) over an opaque base so the blurred content reads clearly; lighter dim. Design mapped via an Explore investigation of the capture/blur pipeline; compiles on both OpenGL (Linux) and DX11 (Windows cross-build). Needs on-device visual verification. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
395 lines
12 KiB
C++
395 lines
12 KiB
C++
// DragonX Wallet - ImGui Edition
|
||
// Copyright 2024-2026 The Hush Developers
|
||
// Released under the GPLv3
|
||
|
||
#pragma once
|
||
|
||
#include "acrylic.h"
|
||
#include "imgui.h"
|
||
|
||
namespace dragonx {
|
||
namespace ui {
|
||
namespace effects {
|
||
|
||
/**
|
||
* @brief ImGui integration for acrylic effects
|
||
*
|
||
* Provides convenient wrappers around AcrylicMaterial for use with
|
||
* standard ImGui rendering patterns.
|
||
*/
|
||
namespace ImGuiAcrylic {
|
||
|
||
// ============================================================================
|
||
// Initialization
|
||
// ============================================================================
|
||
|
||
/**
|
||
* @brief Initialize the acrylic system
|
||
*
|
||
* Call once at application startup, after OpenGL context is created.
|
||
* @return true if successful
|
||
*/
|
||
bool Init();
|
||
|
||
/**
|
||
* @brief Shutdown the acrylic system
|
||
*
|
||
* Call at application shutdown before destroying OpenGL context.
|
||
*/
|
||
void Shutdown();
|
||
|
||
/**
|
||
* @brief Check if acrylic is available and initialized
|
||
*/
|
||
bool IsAvailable();
|
||
|
||
// ============================================================================
|
||
// Frame Operations
|
||
// ============================================================================
|
||
|
||
/**
|
||
* @brief Begin a new frame for acrylic rendering
|
||
*
|
||
* Call this at the start of your render loop, before any ImGui rendering.
|
||
* This captures the current screen content for blur source.
|
||
*
|
||
* @param width Viewport width
|
||
* @param height Viewport height
|
||
*/
|
||
void BeginFrame(int width, int height);
|
||
|
||
/**
|
||
* @brief End the acrylic frame
|
||
*
|
||
* Call this after all regular content is rendered but before acrylic overlays.
|
||
* Captures the current framebuffer content for blur.
|
||
*/
|
||
void CaptureBackground();
|
||
|
||
/**
|
||
* @brief Invalidate the acrylic capture so the next frame re-captures
|
||
* and re-blurs. Call after theme/skin changes that alter the
|
||
* background gradient, image, or colors.
|
||
*/
|
||
void InvalidateCapture();
|
||
|
||
/**
|
||
* @brief Get a draw callback for background capture.
|
||
*
|
||
* Insert this callback at the end of the BackgroundDrawList (after all
|
||
* background commands). During RenderDrawData() it fires right after
|
||
* the background is rasterized — before any UI windows — and blits
|
||
* the clean background into the acrylic capture buffer.
|
||
*
|
||
* Usage in main.cpp:
|
||
* @code
|
||
* bgDL->AddCallback(ImGuiAcrylic::GetBackgroundCaptureCallback(), nullptr);
|
||
* bgDL->AddCallback(ImDrawCallback_ResetRenderState, nullptr);
|
||
* @endcode
|
||
*/
|
||
ImDrawCallback GetBackgroundCaptureCallback();
|
||
|
||
/**
|
||
* @brief Returns a draw callback that captures the LIVE framebuffer (no dirtyFrames_
|
||
* gate). Insert it at the START of a full-window modal overlay's draw list — before the
|
||
* overlay draws its own backdrop — so the acrylic blurs the live app UI behind the modal:
|
||
* @code
|
||
* ImDrawList* dl = ImGui::GetWindowDrawList();
|
||
* dl->AddCallback(ImGuiAcrylic::GetLiveCaptureCallback(), nullptr);
|
||
* dl->AddCallback(ImDrawCallback_ResetRenderState, nullptr);
|
||
* // ... then draw the overlay's acrylic/dim backdrop ...
|
||
* @endcode
|
||
*/
|
||
ImDrawCallback GetLiveCaptureCallback();
|
||
|
||
// ============================================================================
|
||
// Drawing Functions
|
||
// ============================================================================
|
||
|
||
/**
|
||
* @brief Draw an acrylic-filled rectangle
|
||
*
|
||
* @param drawList ImGui draw list to add the rectangle to
|
||
* @param pMin Top-left corner (screen coordinates)
|
||
* @param pMax Bottom-right corner (screen coordinates)
|
||
* @param params Acrylic appearance parameters
|
||
* @param rounding Corner rounding radius
|
||
*/
|
||
void DrawAcrylicRect(ImDrawList* drawList,
|
||
const ImVec2& pMin, const ImVec2& pMax,
|
||
const AcrylicParams& params,
|
||
float rounding = 0.0f);
|
||
|
||
/**
|
||
* @brief Draw an acrylic-filled rectangle with default preset
|
||
*/
|
||
void DrawAcrylicRect(ImDrawList* drawList,
|
||
const ImVec2& pMin, const ImVec2& pMax,
|
||
float rounding = 0.0f);
|
||
|
||
// ============================================================================
|
||
// Window Wrappers
|
||
// ============================================================================
|
||
|
||
/**
|
||
* @brief Begin an acrylic-background window
|
||
*
|
||
* Works like ImGui::Begin but with acrylic background.
|
||
* Must be paired with EndAcrylicWindow().
|
||
*
|
||
* @param name Window name/ID
|
||
* @param p_open Optional close button flag
|
||
* @param flags ImGui window flags
|
||
* @param params Acrylic appearance parameters
|
||
* @return true if window is visible
|
||
*/
|
||
bool BeginAcrylicWindow(const char* name, bool* p_open = nullptr,
|
||
ImGuiWindowFlags flags = 0,
|
||
const AcrylicParams& params = AcrylicMaterial::getPopupPreset());
|
||
|
||
/**
|
||
* @brief End an acrylic window
|
||
*/
|
||
void EndAcrylicWindow();
|
||
|
||
// ============================================================================
|
||
// Child Region Wrappers
|
||
// ============================================================================
|
||
|
||
/**
|
||
* @brief Begin an acrylic child region
|
||
*
|
||
* Works like ImGui::BeginChild but with acrylic background.
|
||
* Must be paired with EndAcrylicChild().
|
||
*
|
||
* @param str_id Child region ID
|
||
* @param size Child region size (0,0 = auto)
|
||
* @param params Acrylic appearance parameters
|
||
* @param child_flags ImGui child flags
|
||
* @param window_flags ImGui window flags for the child
|
||
* @return true if child is visible
|
||
*/
|
||
bool BeginAcrylicChild(const char* str_id,
|
||
const ImVec2& size = ImVec2(0, 0),
|
||
const AcrylicParams& params = AcrylicMaterial::getDarkPreset(),
|
||
ImGuiChildFlags child_flags = 0,
|
||
ImGuiWindowFlags window_flags = 0);
|
||
|
||
/**
|
||
* @brief End an acrylic child region
|
||
*/
|
||
void EndAcrylicChild();
|
||
|
||
// ============================================================================
|
||
// Popup Wrappers
|
||
// ============================================================================
|
||
|
||
/**
|
||
* @brief Begin an acrylic popup
|
||
*
|
||
* Works like ImGui::BeginPopup but with acrylic background.
|
||
* Must be paired with EndAcrylicPopup().
|
||
*
|
||
* @param str_id Popup ID
|
||
* @param flags ImGui window flags
|
||
* @param params Acrylic appearance parameters
|
||
* @return true if popup is open
|
||
*/
|
||
bool BeginAcrylicPopup(const char* str_id,
|
||
ImGuiWindowFlags flags = 0,
|
||
const AcrylicParams& params = AcrylicMaterial::getPopupPreset());
|
||
|
||
/**
|
||
* @brief End an acrylic popup
|
||
*/
|
||
void EndAcrylicPopup();
|
||
|
||
/**
|
||
* @brief Begin an acrylic modal popup
|
||
*
|
||
* Works like ImGui::BeginPopupModal but with acrylic background.
|
||
* Must be paired with EndAcrylicPopup().
|
||
*/
|
||
bool BeginAcrylicPopupModal(const char* name, bool* p_open = nullptr,
|
||
ImGuiWindowFlags flags = 0,
|
||
const AcrylicParams& params = AcrylicMaterial::getPopupPreset());
|
||
|
||
// ============================================================================
|
||
// Context Menu Helpers
|
||
// ============================================================================
|
||
|
||
/**
|
||
* @brief Begin an acrylic context menu for the last item
|
||
*
|
||
* Works like ImGui::BeginPopupContextItem but with acrylic background.
|
||
* Must be paired with EndAcrylicPopup().
|
||
*
|
||
* @param str_id Popup ID (nullptr to use last item ID)
|
||
* @param popup_flags ImGui popup flags
|
||
* @param params Acrylic appearance parameters
|
||
* @return true if context menu is open
|
||
*/
|
||
bool BeginAcrylicContextItem(const char* str_id = nullptr,
|
||
ImGuiPopupFlags popup_flags = 0,
|
||
const AcrylicParams& params = AcrylicMaterial::getPopupPreset());
|
||
|
||
/**
|
||
* @brief Begin an acrylic context menu for the current window
|
||
*
|
||
* Works like ImGui::BeginPopupContextWindow but with acrylic background.
|
||
* Must be paired with EndAcrylicPopup().
|
||
*/
|
||
bool BeginAcrylicContextWindow(const char* str_id = nullptr,
|
||
ImGuiPopupFlags popup_flags = 0,
|
||
const AcrylicParams& params = AcrylicMaterial::getPopupPreset());
|
||
|
||
// ============================================================================
|
||
// Sidebar Helper
|
||
// ============================================================================
|
||
|
||
/**
|
||
* @brief Draw an acrylic sidebar background
|
||
*
|
||
* Convenience function for drawing sidebar with DragonX branded acrylic.
|
||
*
|
||
* @param width Sidebar width
|
||
* @param params Optional custom parameters (default: sidebar preset)
|
||
*/
|
||
void DrawSidebarBackground(float width,
|
||
const AcrylicParams& params = AcrylicMaterial::getSidebarPreset());
|
||
|
||
// ============================================================================
|
||
// Settings
|
||
// ============================================================================
|
||
|
||
/**
|
||
* @brief Set global acrylic quality
|
||
*/
|
||
void SetQuality(AcrylicQuality quality);
|
||
|
||
/**
|
||
* @brief Get current quality setting
|
||
*/
|
||
AcrylicQuality GetQuality();
|
||
|
||
/**
|
||
* @brief Enable/disable acrylic globally
|
||
*
|
||
* When disabled, all acrylic functions fall back to solid colors.
|
||
*/
|
||
void SetEnabled(bool enabled);
|
||
|
||
/**
|
||
* @brief Check if acrylic is enabled
|
||
*/
|
||
bool IsEnabled();
|
||
|
||
/**
|
||
* @brief Set blur radius multiplier (scales all blur radii)
|
||
* @param multiplier Value from 0.5 to 2.0 (1.0 = default)
|
||
*/
|
||
void SetBlurMultiplier(float multiplier);
|
||
|
||
/**
|
||
* @brief Get current blur multiplier
|
||
*/
|
||
float GetBlurMultiplier();
|
||
|
||
/**
|
||
* @brief Set reduced transparency mode (accessibility)
|
||
*
|
||
* When enabled, uses solid fallback colors instead of blur effects.
|
||
*/
|
||
void SetReducedTransparency(bool reduced);
|
||
|
||
/**
|
||
* @brief Check if reduced transparency mode is active
|
||
*/
|
||
bool GetReducedTransparency();
|
||
|
||
/**
|
||
* @brief Set UI opacity multiplier for cards/sidebar (0.3–1.0, 1=opaque)
|
||
*/
|
||
void SetUIOpacity(float opacity);
|
||
|
||
/**
|
||
* @brief Get UI opacity multiplier
|
||
*/
|
||
float GetUIOpacity();
|
||
|
||
/**
|
||
* @brief Set noise opacity multiplier (0.0 = no noise, 1.0 = default, 2.0 = max)
|
||
*/
|
||
void SetNoiseOpacity(float multiplier);
|
||
|
||
/**
|
||
* @brief Get noise opacity multiplier
|
||
*/
|
||
float GetNoiseOpacity();
|
||
|
||
/**
|
||
* @brief Get full acrylic settings
|
||
*/
|
||
const AcrylicSettings& GetSettings();
|
||
|
||
/**
|
||
* @brief Set full acrylic settings
|
||
*/
|
||
void SetSettings(const AcrylicSettings& settings);
|
||
|
||
// ============================================================================
|
||
// Presets — combined quality + blur amount
|
||
// ============================================================================
|
||
|
||
/// Number of built-in presets (Off … Frosted)
|
||
constexpr int kPresetCount = 6;
|
||
|
||
/**
|
||
* @brief Apply a preset that sets both quality and blur multiplier.
|
||
* @param preset Index 0–5 (Off, Subtle, Light, Standard, Strong, Frosted)
|
||
*/
|
||
void SetPreset(int preset);
|
||
|
||
/**
|
||
* @brief Derive the closest preset index from current quality + blur.
|
||
*/
|
||
int GetPreset();
|
||
|
||
/**
|
||
* @brief Human-readable label for a preset index.
|
||
*/
|
||
const char* GetPresetLabel(int preset);
|
||
|
||
/**
|
||
* @brief Get the quality enum for a given preset index.
|
||
*/
|
||
AcrylicQuality PresetQuality(int preset);
|
||
|
||
/**
|
||
* @brief Get the blur multiplier for a given preset index.
|
||
*/
|
||
float PresetBlur(int preset);
|
||
|
||
/**
|
||
* @brief Find closest preset matching a quality + blur pair.
|
||
* Useful for migrating from legacy separate settings.
|
||
*/
|
||
int MatchPreset(AcrylicQuality quality, float blur);
|
||
|
||
/**
|
||
* @brief Apply a continuous blur amount.
|
||
*
|
||
* Uses Low quality (like the old "Subtle" preset) at any non-zero blur
|
||
* level, giving fine-grained control without stepped presets.
|
||
* When blur is near zero the effect is disabled entirely.
|
||
*
|
||
* @param blur Blur multiplier (0.0 = off, up to 4.0 = maximum)
|
||
*/
|
||
void ApplyBlurAmount(float blur);
|
||
|
||
} // namespace ImGuiAcrylic
|
||
|
||
} // namespace effects
|
||
} // namespace ui
|
||
} // namespace dragonx
|