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:
2026-02-27 00:26:01 -06:00
commit 3aee55b49c
306 changed files with 177789 additions and 0 deletions
+456
View File
@@ -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