ObsidianDragon - DragonX ImGui Wallet
Full-node GUI wallet for DragonX cryptocurrency. Built with Dear ImGui, SDL3, and OpenGL3/DX11. Features: - Send/receive shielded and transparent transactions - Autoshield with merged transaction display - Built-in CPU mining (xmrig) - Peer management and network monitoring - Wallet encryption with PIN lock - QR code generation for receive addresses - Transaction history with pagination - Console for direct RPC commands - Cross-platform (Linux, Windows)
This commit is contained in:
@@ -0,0 +1,456 @@
|
||||
// DragonX Wallet - ImGui Edition
|
||||
// Copyright 2024-2026 The Hush Developers
|
||||
// Released under the GPLv3
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "framebuffer.h"
|
||||
#include "blur_shader.h"
|
||||
#include "noise_texture.h"
|
||||
#include "imgui.h"
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
||||
#ifdef DRAGONX_USE_DX11
|
||||
#include <d3d11.h>
|
||||
#endif
|
||||
|
||||
namespace dragonx {
|
||||
namespace ui {
|
||||
namespace effects {
|
||||
|
||||
/**
|
||||
* @brief Acrylic material parameters
|
||||
*
|
||||
* These parameters control the appearance of the acrylic effect,
|
||||
* matching Microsoft's Fluent Design system.
|
||||
*/
|
||||
struct AcrylicParams {
|
||||
// Tint color (RGBA, pre-multiplied alpha)
|
||||
ImVec4 tintColor = ImVec4(0.1f, 0.1f, 0.12f, 1.0f);
|
||||
|
||||
// Tint opacity (0.0 = fully transparent, 1.0 = fully opaque)
|
||||
float tintOpacity = 0.75f;
|
||||
|
||||
// Luminosity opacity (controls saturation pass-through)
|
||||
// Lower values = more desaturated/milky appearance
|
||||
float luminosityOpacity = 0.5f;
|
||||
|
||||
// Blur radius in pixels (typical: 20-60)
|
||||
float blurRadius = 30.0f;
|
||||
|
||||
// Noise texture opacity (typical: 0.02-0.04)
|
||||
float noiseOpacity = 0.02f;
|
||||
|
||||
// Fallback color when acrylic is disabled.
|
||||
// The alpha channel also controls the glass opacity of the blurred
|
||||
// background when acrylic IS active (lower alpha = more see-through).
|
||||
ImVec4 fallbackColor = ImVec4(0.15f, 0.15f, 0.18f, 0.5f);
|
||||
|
||||
// Whether acrylic is enabled (false = use fallback)
|
||||
bool enabled = true;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Acrylic quality levels
|
||||
*/
|
||||
enum class AcrylicQuality {
|
||||
Off, // Solid fallback color only
|
||||
Low, // Single blur pass, downsampled
|
||||
Medium, // Two blur passes, slight downsample
|
||||
High // Full quality blur
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Acrylic fallback modes for graceful degradation
|
||||
*/
|
||||
enum class AcrylicFallback {
|
||||
None, // Full acrylic (blur + tint + noise)
|
||||
TintedOnly, // No blur, just semi-transparent tint overlay
|
||||
Solid // Opaque fallback color only
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Acrylic settings for accessibility and performance
|
||||
*/
|
||||
struct AcrylicSettings {
|
||||
bool enabled = true; // Master toggle
|
||||
bool reducedTransparency = false; // Accessibility: use solid colors
|
||||
float uiOpacity = 1.0f; // Card/sidebar opacity multiplier (0.3–1.0)
|
||||
AcrylicQuality quality = AcrylicQuality::Medium; // Medium default for balance of quality/performance
|
||||
float blurRadiusMultiplier = 1.0f; // Scales all blur radii (0.5 - 2.0)
|
||||
float noiseOpacityMultiplier = 1.0f; // Scales noise opacity (0.0 - 2.0)
|
||||
|
||||
// Auto-disable conditions (checked each frame)
|
||||
bool disableOnBattery = false; // Disable when on battery power
|
||||
bool disableOnLowFPS = false; // Disable if FPS drops below threshold
|
||||
float lowFPSThreshold = 30.0f; // FPS threshold for auto-disable
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief System capabilities for acrylic effects
|
||||
*/
|
||||
struct AcrylicCapabilities {
|
||||
bool hasFramebufferSupport = false;
|
||||
bool hasShaderSupport = false;
|
||||
bool hasTextureSupport = false;
|
||||
int maxTextureSize = 0;
|
||||
std::string glVersion;
|
||||
std::string glRenderer;
|
||||
bool isLowEndGPU = false;
|
||||
bool isOnBattery = false; // Linux: check /sys/class/power_supply
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Main acrylic material rendering system
|
||||
*
|
||||
* Implements Microsoft Fluent Design's acrylic material effect:
|
||||
* - Gaussian blur of background content
|
||||
* - Tint color overlay
|
||||
* - Luminosity blend for depth
|
||||
* - Subtle noise texture for grain
|
||||
*/
|
||||
class AcrylicMaterial {
|
||||
public:
|
||||
AcrylicMaterial();
|
||||
~AcrylicMaterial();
|
||||
|
||||
// Non-copyable
|
||||
AcrylicMaterial(const AcrylicMaterial&) = delete;
|
||||
AcrylicMaterial& operator=(const AcrylicMaterial&) = delete;
|
||||
|
||||
/**
|
||||
* @brief Initialize the acrylic system
|
||||
* @return true if successful
|
||||
*/
|
||||
bool init();
|
||||
|
||||
/**
|
||||
* @brief Release all resources
|
||||
*/
|
||||
void shutdown();
|
||||
|
||||
/**
|
||||
* @brief Check if system is initialized
|
||||
*/
|
||||
bool isInitialized() const { return initialized_; }
|
||||
|
||||
/**
|
||||
* @brief Update internal buffers for new viewport size
|
||||
* @param width Viewport width
|
||||
* @param height Viewport height
|
||||
*/
|
||||
void resize(int width, int height);
|
||||
|
||||
/**
|
||||
* @brief Capture current screen content for blur source
|
||||
*
|
||||
* Call this BEFORE rendering any acrylic surfaces.
|
||||
* Only recaptures when the background is marked dirty.
|
||||
*/
|
||||
void captureBackground();
|
||||
|
||||
/**
|
||||
* @brief Capture background directly from the current framebuffer.
|
||||
*
|
||||
* Intended to be called from an ImGui draw callback inserted at
|
||||
* the end of the BackgroundDrawList. At that point during
|
||||
* RenderDrawData(), only the background (gradient / image / noise)
|
||||
* has been rasterized — no UI elements are in the framebuffer yet.
|
||||
* This gives a clean background capture for acrylic blur.
|
||||
*
|
||||
* Respects the dirtyFrames_ counter so the capture and blur
|
||||
* are only recomputed when the background actually changes
|
||||
* (resize, theme change, etc.).
|
||||
*/
|
||||
void captureBackgroundDirect();
|
||||
|
||||
/**
|
||||
* @brief Returns true once a valid background capture has been made.
|
||||
*
|
||||
* drawRect() checks this and falls back to a tinted fill on the
|
||||
* very first frame before the callback has fired.
|
||||
*/
|
||||
bool hasValidCapture() const { return hasValidCapture_; }
|
||||
|
||||
/// Mark background as needing recapture (call on resize, theme change, etc.)
|
||||
/// Uses a 2-frame counter so the capture re-runs after the new background
|
||||
/// has actually been rendered (theme switch happens mid-frame, before the
|
||||
/// BackgroundDrawList is rebuilt with new colors/images).
|
||||
void markBackgroundDirty() { dirtyFrames_ = 2; }
|
||||
|
||||
/**
|
||||
* @brief Render an acrylic-filled rectangle
|
||||
*
|
||||
* @param drawList ImGui draw list to add commands to
|
||||
* @param pMin Top-left corner in screen coordinates
|
||||
* @param pMax Bottom-right corner in screen coordinates
|
||||
* @param params Acrylic parameters
|
||||
* @param rounding Corner rounding
|
||||
*/
|
||||
void drawRect(ImDrawList* drawList, const ImVec2& pMin, const ImVec2& pMax,
|
||||
const AcrylicParams& params, float rounding = 0.0f);
|
||||
|
||||
/**
|
||||
* @brief Get the blurred background texture for manual rendering
|
||||
*/
|
||||
ImTextureID getBlurredTexture() const;
|
||||
|
||||
/**
|
||||
* @brief Get the noise texture
|
||||
*/
|
||||
ImTextureID getNoiseTexture() const;
|
||||
|
||||
// ========================================================================
|
||||
// Settings
|
||||
// ========================================================================
|
||||
|
||||
/**
|
||||
* @brief Set global acrylic quality
|
||||
*/
|
||||
void setQuality(AcrylicQuality quality);
|
||||
AcrylicQuality getQuality() const { return settings_.quality; }
|
||||
|
||||
/**
|
||||
* @brief Enable/disable acrylic globally
|
||||
*/
|
||||
void setEnabled(bool enabled) { settings_.enabled = enabled; }
|
||||
bool isEnabled() const { return settings_.enabled; }
|
||||
|
||||
/**
|
||||
* @brief Set blur radius multiplier (scales all blur radii)
|
||||
* @param multiplier Value from 0.0 to 5.0
|
||||
*/
|
||||
void setBlurMultiplier(float multiplier) {
|
||||
float clamped = std::max(0.0f, std::min(5.0f, multiplier));
|
||||
settings_.blurRadiusMultiplier = clamped;
|
||||
}
|
||||
float getBlurMultiplier() const { return settings_.blurRadiusMultiplier; }
|
||||
|
||||
/**
|
||||
* @brief Set reduced transparency mode (accessibility)
|
||||
*/
|
||||
void setReducedTransparency(bool reduced) { settings_.reducedTransparency = reduced; }
|
||||
bool getReducedTransparency() const { return settings_.reducedTransparency; }
|
||||
|
||||
/**
|
||||
* @brief Set UI opacity multiplier for cards/sidebar (0.3–1.0, 1=opaque)
|
||||
*/
|
||||
void setUIOpacity(float opacity) {
|
||||
settings_.uiOpacity = std::max(0.3f, std::min(1.0f, opacity));
|
||||
}
|
||||
float getUIOpacity() const { return settings_.uiOpacity; }
|
||||
|
||||
/**
|
||||
* @brief Set noise opacity multiplier (0.0 = no noise, 1.0 = default, 2.0 = double)
|
||||
*/
|
||||
void setNoiseOpacityMultiplier(float m) {
|
||||
settings_.noiseOpacityMultiplier = std::max(0.0f, std::min(5.0f, m));
|
||||
}
|
||||
float getNoiseOpacityMultiplier() const { return settings_.noiseOpacityMultiplier; }
|
||||
|
||||
/**
|
||||
* @brief Get full settings struct
|
||||
*/
|
||||
const AcrylicSettings& getSettings() const { return settings_; }
|
||||
void setSettings(const AcrylicSettings& settings) { settings_ = settings; }
|
||||
|
||||
// ========================================================================
|
||||
// Fallback System
|
||||
// ========================================================================
|
||||
|
||||
/**
|
||||
* @brief Detect system capabilities and determine fallback mode
|
||||
*
|
||||
* Checks OpenGL capabilities, GPU info, and user preferences to
|
||||
* determine the appropriate rendering mode.
|
||||
*
|
||||
* @return The recommended fallback mode
|
||||
*/
|
||||
AcrylicFallback detectFallback() const;
|
||||
|
||||
/**
|
||||
* @brief Get current fallback mode (cached)
|
||||
*/
|
||||
AcrylicFallback getCurrentFallback() const { return currentFallback_; }
|
||||
|
||||
/**
|
||||
* @brief Force a specific fallback mode
|
||||
*/
|
||||
void setForcedFallback(AcrylicFallback fallback) {
|
||||
forcedFallback_ = fallback;
|
||||
hasForcedFallback_ = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Clear forced fallback and use auto-detection
|
||||
*/
|
||||
void clearForcedFallback() { hasForcedFallback_ = false; }
|
||||
|
||||
/**
|
||||
* @brief Get detected system capabilities
|
||||
*/
|
||||
const AcrylicCapabilities& getCapabilities() const { return capabilities_; }
|
||||
|
||||
/**
|
||||
* @brief Refresh capability detection (call after context changes)
|
||||
*/
|
||||
void refreshCapabilities();
|
||||
|
||||
// ========================================================================
|
||||
// Preset Parameters
|
||||
// ========================================================================
|
||||
|
||||
/**
|
||||
* @brief Get dark theme acrylic preset
|
||||
*/
|
||||
static AcrylicParams getDarkPreset();
|
||||
|
||||
/**
|
||||
* @brief Get light theme acrylic preset
|
||||
*/
|
||||
static AcrylicParams getLightPreset();
|
||||
|
||||
/**
|
||||
* @brief Get DragonX branded acrylic preset
|
||||
*/
|
||||
static AcrylicParams getDragonXPreset();
|
||||
|
||||
/**
|
||||
* @brief Get popup/dialog acrylic preset
|
||||
*/
|
||||
static AcrylicParams getPopupPreset();
|
||||
|
||||
/**
|
||||
* @brief Get sidebar acrylic preset
|
||||
*/
|
||||
static AcrylicParams getSidebarPreset();
|
||||
|
||||
private:
|
||||
/**
|
||||
* @brief Apply blur passes to captured content
|
||||
*/
|
||||
void applyBlur(float radius);
|
||||
|
||||
/**
|
||||
* @brief Composite final acrylic appearance
|
||||
*/
|
||||
void compositeAcrylic(const ImVec2& pMin, const ImVec2& pMax,
|
||||
const AcrylicParams& params);
|
||||
|
||||
/**
|
||||
* @brief Check if effect should be skipped (settings/quality)
|
||||
*/
|
||||
bool shouldSkipEffect() const;
|
||||
|
||||
/**
|
||||
* @brief Draw tinted-only fallback (no blur)
|
||||
*/
|
||||
void drawTintedRect(ImDrawList* drawList, const ImVec2& pMin, const ImVec2& pMax,
|
||||
const AcrylicParams& params, float rounding);
|
||||
|
||||
bool initialized_ = false;
|
||||
AcrylicSettings settings_; // All settings in one struct
|
||||
|
||||
// Fallback system
|
||||
AcrylicCapabilities capabilities_;
|
||||
AcrylicFallback currentFallback_ = AcrylicFallback::None;
|
||||
AcrylicFallback forcedFallback_ = AcrylicFallback::None;
|
||||
bool hasForcedFallback_ = false;
|
||||
|
||||
// Screen dimensions
|
||||
int viewportWidth_ = 0;
|
||||
int viewportHeight_ = 0;
|
||||
|
||||
// Noise texture config
|
||||
int noiseTextureSize_ = 256; // Texture resolution (larger = less repetition)
|
||||
|
||||
// Caching for performance
|
||||
float lastBlurRadius_ = 0.0f;
|
||||
bool blurCacheValid_ = false;
|
||||
int dirtyFrames_ = 2; // >0 means recapture needed; counts down each frame
|
||||
bool hasValidCapture_ = false; // true once a clean BG capture exists
|
||||
|
||||
// Capture and blur framebuffers
|
||||
Framebuffer captureBuffer_;
|
||||
FramebufferPingPong blurBuffers_;
|
||||
|
||||
// Shaders
|
||||
BlurShader blurShader_;
|
||||
|
||||
// Fullscreen quad for post-processing
|
||||
FullscreenQuad quad_;
|
||||
|
||||
// Noise texture
|
||||
NoiseTexture noiseTexture_;
|
||||
|
||||
// Composite shader (tint + noise overlay)
|
||||
GLuint compositeShader_ = 0;
|
||||
GLint uCompositeTintColor_ = -1;
|
||||
GLint uCompositeTintOpacity_ = -1;
|
||||
GLint uCompositeLuminosity_ = -1;
|
||||
GLint uCompositeNoiseOpacity_ = -1;
|
||||
GLint uCompositeBlurTex_ = -1;
|
||||
GLint uCompositeNoiseTex_ = -1;
|
||||
GLint uCompositeTexScale_ = -1;
|
||||
|
||||
#ifdef DRAGONX_USE_DX11
|
||||
// ---- DX11 acrylic resources (used instead of GL objects above) ----
|
||||
ID3D11Device* dx_device_ = nullptr;
|
||||
ID3D11DeviceContext* dx_context_ = nullptr;
|
||||
|
||||
// Capture buffer (full viewport resolution)
|
||||
ID3D11Texture2D* dx_captureTex_ = nullptr;
|
||||
ID3D11ShaderResourceView* dx_captureSRV_ = nullptr;
|
||||
ID3D11RenderTargetView* dx_captureRTV_ = nullptr;
|
||||
|
||||
// Blur ping-pong buffers (possibly downscaled)
|
||||
ID3D11Texture2D* dx_blurTex_[2] = {};
|
||||
ID3D11ShaderResourceView* dx_blurSRV_[2] = {};
|
||||
ID3D11RenderTargetView* dx_blurRTV_[2] = {};
|
||||
int dx_blurWidth_ = 0;
|
||||
int dx_blurHeight_ = 0;
|
||||
int dx_blurCurrent_ = 0; // which buffer is "source"
|
||||
|
||||
// Shaders & pipeline objects
|
||||
ID3D11VertexShader* dx_blurVS_ = nullptr;
|
||||
ID3D11PixelShader* dx_blurPS_ = nullptr;
|
||||
ID3D11InputLayout* dx_inputLayout_ = nullptr;
|
||||
ID3D11Buffer* dx_blurCB_ = nullptr;
|
||||
ID3D11Buffer* dx_vertexBuf_ = nullptr;
|
||||
ID3D11SamplerState* dx_sampler_ = nullptr;
|
||||
ID3D11RasterizerState* dx_blurRS_ = nullptr;
|
||||
ID3D11BlendState* dx_blurBS_ = nullptr;
|
||||
ID3D11DepthStencilState* dx_blurDSS_ = nullptr;
|
||||
|
||||
// Noise texture (DX11)
|
||||
ID3D11Texture2D* dx_noiseTex_ = nullptr;
|
||||
ID3D11ShaderResourceView* dx_noiseSRV_ = nullptr;
|
||||
|
||||
// Internal helpers
|
||||
bool dx_initPipeline();
|
||||
void dx_releasePipeline();
|
||||
void dx_createRenderTarget(ID3D11Texture2D*& tex,
|
||||
ID3D11ShaderResourceView*& srv,
|
||||
ID3D11RenderTargetView*& rtv,
|
||||
int w, int h,
|
||||
DXGI_FORMAT format);
|
||||
void dx_releaseRenderTarget(ID3D11Texture2D*& tex,
|
||||
ID3D11ShaderResourceView*& srv,
|
||||
ID3D11RenderTargetView*& rtv);
|
||||
#endif // DRAGONX_USE_DX11
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// Global Acrylic Instance
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* @brief Get the global acrylic material instance
|
||||
*/
|
||||
AcrylicMaterial& getAcrylicMaterial();
|
||||
|
||||
} // namespace effects
|
||||
} // namespace ui
|
||||
} // namespace dragonx
|
||||
Reference in New Issue
Block a user