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:
288
src/ui/material/typography.h
Normal file
288
src/ui/material/typography.h
Normal file
@@ -0,0 +1,288 @@
|
||||
// DragonX Wallet - ImGui Edition
|
||||
// Copyright 2024-2026 The Hush Developers
|
||||
// Released under the GPLv3
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "imgui.h"
|
||||
#include <string>
|
||||
|
||||
namespace dragonx {
|
||||
namespace ui {
|
||||
namespace material {
|
||||
|
||||
// ============================================================================
|
||||
// Material Design Type Scale
|
||||
// ============================================================================
|
||||
// Based on https://m2.material.io/design/typography/the-type-system.html
|
||||
//
|
||||
// The type scale is a combination of 13 styles that are supported by the
|
||||
// type system. It contains reusable categories of text, each with an
|
||||
// intended application and meaning.
|
||||
|
||||
/**
|
||||
* @brief Material Design typography style identifiers
|
||||
*/
|
||||
enum class TypeStyle {
|
||||
H1, // 96sp Light - Large display headers
|
||||
H2, // 60sp Light - Display headers
|
||||
H3, // 48sp Regular - Section titles
|
||||
H4, // 34sp Regular - Section titles
|
||||
H5, // 24sp Regular - Card titles, dialog titles
|
||||
H6, // 20sp Medium - Section headers, subtitles
|
||||
Subtitle1, // 16sp Regular - Secondary information
|
||||
Subtitle2, // 14sp Medium - Secondary information
|
||||
Body1, // 16sp Regular - Primary body text
|
||||
Body2, // 14sp Regular - Secondary body text
|
||||
Button, // 14sp Medium - Button labels (uppercase)
|
||||
Caption, // 12sp Regular - Timestamps, labels
|
||||
Overline, // 10sp Regular - Overline labels (uppercase)
|
||||
ButtonSm, // Small button labels
|
||||
ButtonLg // Large button labels
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Typography specification for a type style
|
||||
*/
|
||||
struct TypeSpec {
|
||||
float size; // Font size in sp (scaled pixels)
|
||||
float letterSpacing; // Letter spacing in px (applied after scaling)
|
||||
float lineHeight; // Line height multiplier
|
||||
bool uppercase; // Whether text should be uppercase
|
||||
|
||||
// Font weight is handled by which font is used (Light/Regular/Medium)
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Typography system managing Material Design fonts
|
||||
*
|
||||
* Loads Ubuntu fonts in Light, Regular, and Medium weights at multiple
|
||||
* sizes to implement the Material Design type scale.
|
||||
*
|
||||
* Usage:
|
||||
* // Initialize during startup (after ImGui context)
|
||||
* dragonx::ui::material::Typography::instance().load(io);
|
||||
*
|
||||
* // Use fonts throughout the application
|
||||
* ImGui::PushFont(Typography::instance().getFont(TypeStyle::H5));
|
||||
* ImGui::Text("Card Title");
|
||||
* ImGui::PopFont();
|
||||
*
|
||||
* // Or use convenience functions
|
||||
* Typography::instance().pushFont(TypeStyle::Body1);
|
||||
* ImGui::TextWrapped("Body text here...");
|
||||
* Typography::instance().popFont();
|
||||
*/
|
||||
class Typography {
|
||||
public:
|
||||
/**
|
||||
* @brief Get the singleton instance
|
||||
*/
|
||||
static Typography& instance();
|
||||
|
||||
/**
|
||||
* @brief Load all fonts for the type scale
|
||||
*
|
||||
* Must be called after ImGui context is created but before first frame.
|
||||
*
|
||||
* @param io ImGui IO reference
|
||||
* @param dpiScale DPI scale factor (default 1.0)
|
||||
* @return true if fonts loaded successfully
|
||||
*/
|
||||
bool load(ImGuiIO& io, float dpiScale = 1.0f);
|
||||
|
||||
/**
|
||||
* @brief Reload fonts at a new DPI scale
|
||||
*
|
||||
* Call when the display scale changes (e.g., window moved to a different
|
||||
* DPI monitor). Clears the existing font atlas and reloads all fonts.
|
||||
*
|
||||
* @param io ImGui IO reference
|
||||
* @param dpiScale New DPI scale factor
|
||||
* @return true if fonts reloaded successfully
|
||||
*/
|
||||
bool reload(ImGuiIO& io, float dpiScale);
|
||||
|
||||
/**
|
||||
* @brief Check if typography system is loaded
|
||||
*/
|
||||
bool isLoaded() const { return loaded_; }
|
||||
|
||||
/**
|
||||
* @brief Get the current DPI scale
|
||||
*/
|
||||
float getDpiScale() const { return dpiScale_; }
|
||||
|
||||
/**
|
||||
* @brief Get font for a type style
|
||||
*
|
||||
* @param style The Material Design type style
|
||||
* @return ImFont pointer (never null, returns default if not loaded)
|
||||
*/
|
||||
ImFont* getFont(TypeStyle style) const;
|
||||
|
||||
/**
|
||||
* @brief Get the spec for a type style
|
||||
*
|
||||
* @param style The Material Design type style
|
||||
* @return TypeSpec with size, spacing, and line height
|
||||
*/
|
||||
const TypeSpec& getSpec(TypeStyle style) const;
|
||||
|
||||
/**
|
||||
* @brief Push font for a type style
|
||||
*
|
||||
* Convenience wrapper around ImGui::PushFont(getFont(style))
|
||||
*/
|
||||
void pushFont(TypeStyle style) const;
|
||||
|
||||
/**
|
||||
* @brief Pop the current font
|
||||
*
|
||||
* Convenience wrapper around ImGui::PopFont()
|
||||
*/
|
||||
void popFont() const;
|
||||
|
||||
// ========================================================================
|
||||
// Font Accessors (for common cases)
|
||||
// ========================================================================
|
||||
|
||||
// Headers
|
||||
ImFont* h1() const { return getFont(TypeStyle::H1); }
|
||||
ImFont* h2() const { return getFont(TypeStyle::H2); }
|
||||
ImFont* h3() const { return getFont(TypeStyle::H3); }
|
||||
ImFont* h4() const { return getFont(TypeStyle::H4); }
|
||||
ImFont* h5() const { return getFont(TypeStyle::H5); }
|
||||
ImFont* h6() const { return getFont(TypeStyle::H6); }
|
||||
|
||||
// Body text
|
||||
ImFont* subtitle1() const { return getFont(TypeStyle::Subtitle1); }
|
||||
ImFont* subtitle2() const { return getFont(TypeStyle::Subtitle2); }
|
||||
ImFont* body1() const { return getFont(TypeStyle::Body1); }
|
||||
ImFont* body2() const { return getFont(TypeStyle::Body2); }
|
||||
|
||||
// UI elements
|
||||
ImFont* button() const { return getFont(TypeStyle::Button); }
|
||||
ImFont* buttonSm() const { return getFont(TypeStyle::ButtonSm); }
|
||||
ImFont* buttonLg() const { return getFont(TypeStyle::ButtonLg); }
|
||||
ImFont* caption() const { return getFont(TypeStyle::Caption); }
|
||||
ImFont* overline() const { return getFont(TypeStyle::Overline); }
|
||||
|
||||
// Icon fonts — Material Design Icons merged at specific pixel sizes
|
||||
// Use these when you need to render an icon at a specific size via AddText/ImGui::Text.
|
||||
// Common sizes: iconSmall (14px), iconMed (18px), iconLarge (24px).
|
||||
ImFont* iconSmall() const { return iconFonts_[0] ? iconFonts_[0] : getFont(TypeStyle::Body2); }
|
||||
ImFont* iconMed() const { return iconFonts_[1] ? iconFonts_[1] : getFont(TypeStyle::Body1); }
|
||||
ImFont* iconLarge() const { return iconFonts_[2] ? iconFonts_[2] : getFont(TypeStyle::H5); }
|
||||
ImFont* iconXL() const { return iconFonts_[3] ? iconFonts_[3] : getFont(TypeStyle::H3); }
|
||||
|
||||
/**
|
||||
* @brief Resolve a font name string to ImFont*
|
||||
* @param name Font name like "button", "button-sm", "button-lg", "h4", "body1"
|
||||
* @return ImFont* pointer, or nullptr if name is empty/unknown
|
||||
*/
|
||||
ImFont* resolveByName(const std::string& name) const {
|
||||
if (name.empty()) return nullptr;
|
||||
if (name == "h1") return h1();
|
||||
if (name == "h2") return h2();
|
||||
if (name == "h3") return h3();
|
||||
if (name == "h4") return h4();
|
||||
if (name == "h5") return h5();
|
||||
if (name == "h6") return h6();
|
||||
if (name == "subtitle1") return subtitle1();
|
||||
if (name == "subtitle2") return subtitle2();
|
||||
if (name == "body1") return body1();
|
||||
if (name == "body2") return body2();
|
||||
if (name == "button") return button();
|
||||
if (name == "button-sm") return buttonSm();
|
||||
if (name == "button-lg") return buttonLg();
|
||||
if (name == "caption") return caption();
|
||||
if (name == "overline") return overline();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
// Text Rendering Helpers
|
||||
// ========================================================================
|
||||
|
||||
/**
|
||||
* @brief Render text with a specific type style
|
||||
*
|
||||
* Handles font push/pop and optional uppercase transformation.
|
||||
*
|
||||
* @param style The type style to use
|
||||
* @param text The text to render
|
||||
*/
|
||||
void text(TypeStyle style, const char* text) const;
|
||||
|
||||
/**
|
||||
* @brief Render wrapped text with a specific type style
|
||||
*
|
||||
* @param style The type style to use
|
||||
* @param text The text to render
|
||||
*/
|
||||
void textWrapped(TypeStyle style, const char* text) const;
|
||||
|
||||
/**
|
||||
* @brief Render colored text with a specific type style
|
||||
*
|
||||
* @param style The type style to use
|
||||
* @param color Text color
|
||||
* @param text The text to render
|
||||
*/
|
||||
void textColored(TypeStyle style, ImU32 color, const char* text) const;
|
||||
|
||||
private:
|
||||
Typography() = default;
|
||||
~Typography() = default;
|
||||
Typography(const Typography&) = delete;
|
||||
Typography& operator=(const Typography&) = delete;
|
||||
|
||||
// Load fonts at a specific size with a specific weight
|
||||
ImFont* loadFont(ImGuiIO& io, int weight, float size, const char* name);
|
||||
|
||||
// Font weight constants
|
||||
static constexpr int kWeightLight = 300;
|
||||
static constexpr int kWeightRegular = 400;
|
||||
static constexpr int kWeightMedium = 500;
|
||||
|
||||
bool loaded_ = false;
|
||||
float dpiScale_ = 1.0f;
|
||||
|
||||
// Fonts for each type style
|
||||
ImFont* fonts_[15] = {};
|
||||
|
||||
// Icon fonts at different sizes: [0]=small(14), [1]=med(18), [2]=large(24), [3]=xl(40)
|
||||
ImFont* iconFonts_[4] = {};
|
||||
static constexpr int kNumIconSizes = 4;
|
||||
|
||||
// Load an icon-only font at a specific pixel size
|
||||
ImFont* loadIconFont(ImGuiIO& io, float size, const char* name);
|
||||
|
||||
// Type specifications
|
||||
static const TypeSpec* getTypeSpecs();
|
||||
static constexpr int kNumStyles = 15;
|
||||
};
|
||||
|
||||
// ============================================================================
|
||||
// Convenience Macros (Optional)
|
||||
// ============================================================================
|
||||
|
||||
// Scoped font push/pop using RAII
|
||||
class ScopedFont {
|
||||
public:
|
||||
explicit ScopedFont(TypeStyle style) {
|
||||
Typography::instance().pushFont(style);
|
||||
}
|
||||
~ScopedFont() {
|
||||
Typography::instance().popFont();
|
||||
}
|
||||
};
|
||||
|
||||
// Usage: MATERIAL_FONT(H5) { ImGui::Text("Title"); }
|
||||
#define MATERIAL_FONT(style) \
|
||||
if (dragonx::ui::material::ScopedFont _font{dragonx::ui::material::TypeStyle::style}; true)
|
||||
|
||||
} // namespace material
|
||||
} // namespace ui
|
||||
} // namespace dragonx
|
||||
Reference in New Issue
Block a user