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,351 @@
|
||||
// DragonX Wallet - ImGui Edition
|
||||
// Copyright 2024-2026 The Hush Developers
|
||||
// Released under the GPLv3
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "imgui.h"
|
||||
|
||||
namespace dragonx {
|
||||
namespace ui {
|
||||
namespace material {
|
||||
|
||||
// ============================================================================
|
||||
// Material Design 8dp Grid System
|
||||
// ============================================================================
|
||||
// All spacing in Material Design is based on an 8dp grid.
|
||||
// https://m2.material.io/design/layout/spacing-methods.html
|
||||
|
||||
constexpr float kGridUnit = 8.0f; // Base unit in dp (device-independent pixels)
|
||||
|
||||
// ============================================================================
|
||||
// Spacing Scale
|
||||
// ============================================================================
|
||||
// Use these values for all margins, padding, and gaps
|
||||
|
||||
namespace spacing {
|
||||
|
||||
constexpr float Xxs = 2.0f; // 0.25x - Very tight spacing
|
||||
constexpr float Xs = 4.0f; // 0.5x - Extra small
|
||||
constexpr float Sm = 8.0f; // 1x - Small (default minimum)
|
||||
constexpr float Md = 16.0f; // 2x - Medium (default standard)
|
||||
constexpr float Lg = 24.0f; // 3x - Large
|
||||
constexpr float Xl = 32.0f; // 4x - Extra large
|
||||
constexpr float Xxl = 40.0f; // 5x - Double extra large
|
||||
constexpr float Xxxl = 48.0f; // 6x - Triple extra large
|
||||
|
||||
// Multiplier helpers
|
||||
constexpr float Grid(float multiplier) { return kGridUnit * multiplier; }
|
||||
|
||||
} // namespace spacing
|
||||
|
||||
// ============================================================================
|
||||
// Component Dimensions
|
||||
// ============================================================================
|
||||
// Standard sizes for Material Design components
|
||||
|
||||
namespace size {
|
||||
|
||||
// Buttons
|
||||
constexpr float ButtonHeight = 36.0f;
|
||||
constexpr float ButtonMinWidth = 64.0f;
|
||||
constexpr float ButtonPaddingH = 16.0f;
|
||||
constexpr float ButtonPaddingV = 8.0f;
|
||||
constexpr float ButtonIconGap = 8.0f; // Gap between icon and label
|
||||
constexpr float ButtonCornerRadius = 4.0f;
|
||||
|
||||
// FAB (Floating Action Button)
|
||||
constexpr float FabSize = 56.0f;
|
||||
constexpr float FabMiniSize = 40.0f;
|
||||
constexpr float FabExtendedHeight = 48.0f;
|
||||
constexpr float FabExtendedPadding = 16.0f;
|
||||
constexpr float FabCornerRadius = 16.0f; // Half of mini size for circle
|
||||
|
||||
// Icons
|
||||
constexpr float IconSize = 24.0f;
|
||||
constexpr float IconSizeSm = 18.0f;
|
||||
constexpr float IconSizeLg = 36.0f;
|
||||
constexpr float IconButtonSize = 48.0f; // Touch target for icon buttons
|
||||
|
||||
// App Bar / Toolbar
|
||||
constexpr float AppBarHeight = 56.0f; // Mobile
|
||||
constexpr float AppBarHeightLarge = 64.0f; // Desktop
|
||||
constexpr float AppBarPadding = 16.0f;
|
||||
|
||||
// Navigation
|
||||
constexpr float NavDrawerWidth = 256.0f;
|
||||
constexpr float NavRailWidth = 72.0f;
|
||||
constexpr float NavItemHeight = 48.0f;
|
||||
constexpr float NavItemPadding = 12.0f;
|
||||
constexpr float NavSectionPadding = 8.0f;
|
||||
|
||||
// Cards
|
||||
constexpr float CardCornerRadius = 4.0f;
|
||||
constexpr float CardPadding = 16.0f;
|
||||
constexpr float CardElevation = 1.0f; // Default elevation in dp
|
||||
|
||||
// Dialogs
|
||||
constexpr float DialogMinWidth = 280.0f;
|
||||
constexpr float DialogMaxWidth = 560.0f;
|
||||
constexpr float DialogPadding = 24.0f;
|
||||
constexpr float DialogTitlePadding = 20.0f;
|
||||
constexpr float DialogActionGap = 8.0f;
|
||||
constexpr float DialogCornerRadius = 4.0f;
|
||||
|
||||
// Lists
|
||||
constexpr float ListItemHeight = 48.0f; // Single line
|
||||
constexpr float ListItemHeightTwoLine = 64.0f;
|
||||
constexpr float ListItemHeightThreeLine = 88.0f;
|
||||
constexpr float ListItemPaddingH = 16.0f;
|
||||
constexpr float ListAvatarSize = 40.0f;
|
||||
constexpr float ListIconMargin = 32.0f;
|
||||
|
||||
// Text Fields
|
||||
constexpr float TextFieldHeight = 56.0f;
|
||||
constexpr float TextFieldPadding = 16.0f;
|
||||
constexpr float TextFieldDenseHeight = 40.0f;
|
||||
constexpr float TextFieldCornerRadius = 4.0f;
|
||||
|
||||
// Chips
|
||||
constexpr float ChipHeight = 32.0f;
|
||||
constexpr float ChipPaddingH = 12.0f;
|
||||
constexpr float ChipCornerRadius = 16.0f;
|
||||
|
||||
// Tabs
|
||||
constexpr float TabHeight = 48.0f;
|
||||
constexpr float TabMinWidth = 90.0f;
|
||||
constexpr float TabMaxWidth = 360.0f;
|
||||
constexpr float TabPaddingH = 16.0f;
|
||||
constexpr float TabIndicatorHeight = 2.0f;
|
||||
|
||||
// Snackbar
|
||||
constexpr float SnackbarMinWidth = 288.0f;
|
||||
constexpr float SnackbarMaxWidth = 568.0f;
|
||||
constexpr float SnackbarHeight = 48.0f;
|
||||
constexpr float SnackbarPadding = 8.0f;
|
||||
constexpr float SnackbarMargin = 8.0f;
|
||||
|
||||
// Dividers
|
||||
constexpr float DividerThickness = 1.0f;
|
||||
constexpr float DividerInset = 16.0f; // For inset dividers
|
||||
|
||||
} // namespace size
|
||||
|
||||
// ============================================================================
|
||||
// Responsive Breakpoints
|
||||
// ============================================================================
|
||||
// Based on Material Design responsive layout grid
|
||||
|
||||
namespace breakpoint {
|
||||
|
||||
constexpr float Xs = 0.0f; // Extra small: 0-599dp
|
||||
constexpr float Sm = 600.0f; // Small: 600-904dp
|
||||
constexpr float Md = 905.0f; // Medium: 905-1239dp
|
||||
constexpr float Lg = 1240.0f; // Large: 1240-1439dp
|
||||
constexpr float Xl = 1440.0f; // Extra large: 1440dp+
|
||||
|
||||
// Returns the current breakpoint category
|
||||
enum class Category { Xs, Sm, Md, Lg, Xl };
|
||||
|
||||
inline Category GetCategory(float windowWidth) {
|
||||
if (windowWidth >= Xl) return Category::Xl;
|
||||
if (windowWidth >= Lg) return Category::Lg;
|
||||
if (windowWidth >= Md) return Category::Md;
|
||||
if (windowWidth >= Sm) return Category::Sm;
|
||||
return Category::Xs;
|
||||
}
|
||||
|
||||
// Margin values for each breakpoint
|
||||
inline float GetMargin(Category cat) {
|
||||
switch (cat) {
|
||||
case Category::Xs: return 16.0f;
|
||||
case Category::Sm: return 32.0f;
|
||||
case Category::Md: return 32.0f; // Or fluid centering
|
||||
case Category::Lg: return 200.0f;
|
||||
case Category::Xl: return 200.0f; // Or fluid centering
|
||||
}
|
||||
return 16.0f;
|
||||
}
|
||||
|
||||
// Column count for each breakpoint
|
||||
inline int GetColumns(Category cat) {
|
||||
switch (cat) {
|
||||
case Category::Xs: return 4;
|
||||
case Category::Sm: return 8;
|
||||
default: return 12;
|
||||
}
|
||||
}
|
||||
|
||||
// Recommended navigation style
|
||||
enum class NavStyle { BottomNav, NavRail, NavDrawer };
|
||||
|
||||
inline NavStyle GetNavStyle(Category cat) {
|
||||
switch (cat) {
|
||||
case Category::Xs: return NavStyle::BottomNav;
|
||||
case Category::Sm:
|
||||
case Category::Md: return NavStyle::NavRail;
|
||||
default: return NavStyle::NavDrawer;
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace breakpoint
|
||||
|
||||
// ============================================================================
|
||||
// Layout Helpers
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* @brief Get current window's breakpoint category
|
||||
*/
|
||||
inline breakpoint::Category GetCurrentBreakpoint() {
|
||||
ImVec2 windowSize = ImGui::GetWindowSize();
|
||||
return breakpoint::GetCategory(windowSize.x);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Get recommended margin for current window
|
||||
*/
|
||||
inline float GetCurrentMargin() {
|
||||
return breakpoint::GetMargin(GetCurrentBreakpoint());
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Add horizontal spacing (uses 8dp grid)
|
||||
* @param units Number of 8dp units (default 1)
|
||||
*/
|
||||
inline void HSpace(float units = 1.0f) {
|
||||
ImGui::SameLine(0, kGridUnit * units);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Add vertical spacing (uses 8dp grid)
|
||||
* @param units Number of 8dp units (default 1)
|
||||
*/
|
||||
inline void VSpace(float units = 1.0f) {
|
||||
ImGui::Dummy(ImVec2(0, kGridUnit * units));
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Begin a padded region
|
||||
* @param padding Padding in pixels (use spacing:: constants)
|
||||
*/
|
||||
inline void BeginPadding(float padding) {
|
||||
ImGui::BeginGroup();
|
||||
ImGui::Dummy(ImVec2(0, padding));
|
||||
ImGui::Indent(padding);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief End a padded region
|
||||
* @param padding Same padding used in BeginPadding
|
||||
*/
|
||||
inline void EndPadding(float padding) {
|
||||
ImGui::Unindent(padding);
|
||||
ImGui::Dummy(ImVec2(0, padding));
|
||||
ImGui::EndGroup();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Center the next item horizontally within available width
|
||||
* @param itemWidth Width of the item to center
|
||||
*/
|
||||
inline void CenterHorizontally(float itemWidth) {
|
||||
float availWidth = ImGui::GetContentRegionAvail().x;
|
||||
float offset = (availWidth - itemWidth) * 0.5f;
|
||||
if (offset > 0) {
|
||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + offset);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Calculate column width for responsive grid
|
||||
* @param numColumns Number of columns to span
|
||||
* @param gutterWidth Gap between columns (default 16dp)
|
||||
*/
|
||||
inline float GetColumnWidth(int numColumns = 1, float gutterWidth = spacing::Md) {
|
||||
float availWidth = ImGui::GetContentRegionAvail().x;
|
||||
auto cat = GetCurrentBreakpoint();
|
||||
int totalColumns = breakpoint::GetColumns(cat);
|
||||
|
||||
float totalGutter = gutterWidth * (totalColumns - 1);
|
||||
float columnWidth = (availWidth - totalGutter) / totalColumns;
|
||||
|
||||
return columnWidth * numColumns + gutterWidth * (numColumns - 1);
|
||||
}
|
||||
|
||||
// ============================================================================
|
||||
// Card Layout Helper
|
||||
// ============================================================================
|
||||
|
||||
struct CardLayout {
|
||||
float width;
|
||||
float minHeight;
|
||||
float padding;
|
||||
float cornerRadius;
|
||||
int elevation;
|
||||
|
||||
CardLayout()
|
||||
: width(0) // 0 = auto width
|
||||
, minHeight(0)
|
||||
, padding(size::CardPadding)
|
||||
, cornerRadius(size::CardCornerRadius)
|
||||
, elevation(1)
|
||||
{}
|
||||
|
||||
CardLayout& Width(float w) { width = w; return *this; }
|
||||
CardLayout& MinHeight(float h) { minHeight = h; return *this; }
|
||||
CardLayout& Padding(float p) { padding = p; return *this; }
|
||||
CardLayout& CornerRadius(float r) { cornerRadius = r; return *this; }
|
||||
CardLayout& Elevation(int e) { elevation = e; return *this; }
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// Navigation Drawer Item
|
||||
// ============================================================================
|
||||
|
||||
struct NavItem {
|
||||
const char* label;
|
||||
const char* icon; // Icon font glyph or nullptr
|
||||
bool selected;
|
||||
bool enabled;
|
||||
|
||||
NavItem(const char* lbl, const char* ico = nullptr)
|
||||
: label(lbl), icon(ico), selected(false), enabled(true)
|
||||
{}
|
||||
|
||||
NavItem& Selected(bool s) { selected = s; return *this; }
|
||||
NavItem& Enabled(bool e) { enabled = e; return *this; }
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// Alignment Helpers
|
||||
// ============================================================================
|
||||
|
||||
/**
|
||||
* @brief Align item to right edge of available space
|
||||
* @param itemWidth Width of the item
|
||||
*/
|
||||
inline void AlignRight(float itemWidth) {
|
||||
float availWidth = ImGui::GetContentRegionAvail().x;
|
||||
ImGui::SetCursorPosX(ImGui::GetCursorPosX() + availWidth - itemWidth);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Push items to start from right side (call before group of items)
|
||||
*/
|
||||
inline void BeginRightAlign() {
|
||||
ImGui::BeginGroup();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief End right-aligned group and position it
|
||||
*/
|
||||
inline void EndRightAlign() {
|
||||
ImGui::EndGroup();
|
||||
float groupWidth = ImGui::GetItemRectSize().x;
|
||||
AlignRight(groupWidth);
|
||||
}
|
||||
|
||||
} // namespace material
|
||||
} // namespace ui
|
||||
} // namespace dragonx
|
||||
Reference in New Issue
Block a user