// DragonX Wallet - ImGui Edition // Copyright 2024-2026 The Hush Developers // Released under the GPLv3 #pragma once #include "imgui.h" #include #include #include namespace dragonx { namespace ui { namespace schema { // ============================================================================ // Color properties shared by all styleable elements // ============================================================================ struct ElementColors { std::string color; // "var(--on-primary)" | "rgba(...)" | "#hex" | "" std::string background; std::string backgroundHover; // null = auto-derive std::string backgroundActive; // null = auto-derive std::string borderColor; }; // ============================================================================ // Element Style Structs // ============================================================================ /** * @brief Style for button elements * * Sentinel values: 0 or -1 = inherit from globals, "" = inherit */ struct ButtonStyle { float width = 0; // 0 = auto-size float height = 0; // 0 = auto from font + padding std::string font; // "" = inherit from globals float padding[2] = {0, 0}; // [h, v] — 0 = inherit float opacity = -1; // -1 = inherit, 0.0-1.0 float borderRadius = -1; // -1 = inherit float borderWidth = -1; // -1 = inherit float minWidth = -1; // -1 = inherit std::string align; // "" | "left" | "center" | "right" ElementColors colors; // Gap between adjacent buttons (layout helper) float gap = 0; }; /** * @brief Style for text input elements */ struct InputStyle { float width = 0; // 0 = auto, -1 = fill remaining float height = 0; // 0 = single-line auto int lines = 0; // 0 = inherit, 1 = single, >1 = multiline std::string font; float padding[2] = {0, 0}; float borderRadius = -1; float borderWidth = -1; ElementColors colors; std::string borderColorFocus; // "var(--primary)" for focus ring std::string placeholderColor; // Ratio-based width (alternative to fixed) float widthRatio = -1; // -1 = not set, 0.0-1.0 = fraction of available float maxWidth = -1; // -1 = no limit }; /** * @brief Style for text labels */ struct LabelStyle { std::string font; std::string color; float opacity = -1; std::string align; int truncate = 0; // 0 = no truncation, >0 = max chars float position = -1; // SameLine label position (-1 = not set) }; /** * @brief Style for table columns */ struct ColumnStyle { float width = -1; std::string font; std::string align; int truncate = 0; }; /** * @brief Style for table elements */ struct TableStyle { float minHeight = -1; float heightRatio = -1; // fraction of available space float bottomReserve = -1; float rowHeight = -1; std::string headerFont; std::string cellFont; std::string borderColor; std::string stripeColor; std::map columns; }; /** * @brief Style for checkbox elements */ struct CheckboxStyle { std::string font; std::string color; std::string checkColor; std::string background; }; /** * @brief Style for combo/dropdown elements */ struct ComboStyle { float width = 0; std::string font; std::string color; std::string background; float borderRadius = -1; int truncate = 0; }; /** * @brief Style for slider elements */ struct SliderStyle { float width = 0; std::string trackColor; std::string fillColor; std::string thumbColor; float thumbRadius = -1; }; /** * @brief Style for windows and dialogs */ struct WindowStyle { float width = 0; float height = 0; float padding[2] = {0, 0}; float borderRadius = -1; float borderWidth = -1; std::string background; std::string borderColor; std::string titleFont; }; /** * @brief Style for separator lines */ struct SeparatorStyle { std::string color; float thickness = -1; float margin[2] = {0, 0}; // [top, bottom] }; /** * @brief Style for DrawList-driven custom elements (progress rings, sparklines, etc.) */ struct DrawElementStyle { std::string color; std::string background; float thickness = -1; float radius = -1; float opacity = -1; float size = -1; // generic size (e.g., QR code size) float height = -1; // Additional named properties for flexible DrawList elements std::map extraColors; std::map extraFloats; /// Look up any extra float by key, returning fallback if absent. float getFloat(const std::string& key, float fallback = 0.0f) const { auto it = extraFloats.find(key); return it != extraFloats.end() ? it->second : fallback; } /// Return size if set (>= 0), else fallback. float sizeOr(float fallback) const { return size >= 0.0f ? size : fallback; } }; /** * @brief Style for spacing (layout helper) */ struct SpacingStyle { float size = 0; }; // ============================================================================ // Responsive overrides // ============================================================================ /** * @brief Per-breakpoint property overrides * * Only non-sentinel values override the base style. Applied on top of * the element's base style when the current window size matches the * breakpoint. */ struct ResponsiveButtonOverride { float width = 0; float height = 0; std::string font; float padding[2] = {0, 0}; }; struct ResponsiveInputOverride { float width = 0; float height = 0; }; // ============================================================================ // Breakpoint definitions // ============================================================================ struct BreakpointDef { float maxWidth = -1; // -1 = no constraint float maxHeight = -1; float minWidth = -1; float minHeight = -1; }; struct BreakpointConfig { BreakpointDef compact; BreakpointDef expanded; }; // ============================================================================ // JSON parsing helpers (implemented in element_styles.cpp) // ============================================================================ // Forward declare nlohmann::json to avoid header dependency namespace detail { // Parse individual style types from a JSON object // These are called by UISchema during load — not for external use void parseButtonStyle(const void* jsonObj, ButtonStyle& out); void parseInputStyle(const void* jsonObj, InputStyle& out); void parseLabelStyle(const void* jsonObj, LabelStyle& out); void parseTableStyle(const void* jsonObj, TableStyle& out); void parseCheckboxStyle(const void* jsonObj, CheckboxStyle& out); void parseComboStyle(const void* jsonObj, ComboStyle& out); void parseSliderStyle(const void* jsonObj, SliderStyle& out); void parseWindowStyle(const void* jsonObj, WindowStyle& out); void parseSeparatorStyle(const void* jsonObj, SeparatorStyle& out); void parseDrawElementStyle(const void* jsonObj, DrawElementStyle& out); void parseBreakpointConfig(const void* jsonObj, BreakpointConfig& out); void parseElementColors(const void* jsonObj, ElementColors& out); void parseResponsiveButtonOverride(const void* jsonObj, ResponsiveButtonOverride& out); } // ============================================================================ // Merge helpers — apply overlay on top of base (non-sentinel values win) // ============================================================================ void mergeButton(ButtonStyle& base, const ButtonStyle& overlay); void mergeInput(InputStyle& base, const InputStyle& overlay); void mergeLabel(LabelStyle& base, const LabelStyle& overlay); void mergeWindow(WindowStyle& base, const WindowStyle& overlay); void applyResponsiveButton(ButtonStyle& base, const ResponsiveButtonOverride& ovr); } // namespace schema } // namespace ui } // namespace dragonx