How to Customize Themes and UI Configuration in ArmorPaint
ArmorPaint's visual appearance is controlled by a global g_theme structure that defines colors, dimensions, and layout parameters, enabling deep UI customization through source code modification, runtime patching, or JSON configuration files.
ArmorPaint (from the armory3d/armorpaint repository) implements its user interface through the Kinc UI layer, utilizing a centralized theming system that decouples visual styling from drawing logic. The global g_theme structure, accessed throughout paint/sources/ui/, stores every color value, size constant, and layout flag used when rendering windows, toolbars, sidebars, and menus. By manipulating this structure, you can transform the application's entire look-and-feel without touching the underlying drawing code.
Understanding the Global g_theme Structure
The g_theme struct serves as the single source of truth for all UI cosmetic properties in ArmorPaint. When the application initializes, this structure is populated with default values that subsequent drawing routines reference via direct field access. Because the theme is global, any modification—whether compiled into the binary or applied at runtime—immediately propagates to all interface elements.
Key fields within g_theme include hexadecimal color values for backgrounds and separators, pixel dimensions for buttons and scrollbars, and boolean flags controlling shadows and fill behaviors. The UI code in paint/sources/ui/ reads these fields every frame, ensuring dynamic theme changes take effect instantly.
Key Theme Parameters and Default Values
The g_theme structure exposes granular control over ArmorPaint's interface aesthetics. The following parameters represent the most commonly customized fields:
WINDOW_BG_COL– Background color of primary windows (default:0xff2d2d2d)SEPARATOR_COL– Color of divider lines between UI sections (default:0xff4b4b4b)HIGHLIGHT_COL– Accent color for selected or active elements (default:0xffc0c0c0)BUTTON_COL– Default button background color (defaults toWINDOW_BG_COL)ELEMENT_H– Standard height in pixels for UI components (default:28)BUTTON_H– Specific height for button elements (typically set equal toELEMENT_H)FILL_BUTTON_BG– Boolean controlling whether buttons render solid backgrounds (default:true)SHADOWS– Boolean enabling drop-shadow effects under UI elements (default:true)SCROLL_W– Width of full scrollbars in pixels (default:12)SCROLL_MINI_W– Width of minimized scrollbars (default:8)
Three Methods to Customize ArmorPaint Themes
You can customize the interface through three distinct approaches, each offering different trade-offs between permanence, flexibility, and ease of distribution.
Method 1: Editing Source and Rebuilding
For permanent, baked-in theme changes, modify the default value assignments in the theme initialization code. This typically occurs in paint/sources/util/util_ui.c or within the Kinc UI startup routine.
After adjusting the hex colors or dimension values, recompile the project using make or your platform-specific build scripts. The resulting binary will contain your custom theme as the new default, eliminating the need for external configuration files.
Method 2: Runtime Patching in main.c
To override themes programmatically without rebuilding the entire application, insert assignment statements early in main.c or any initialization function that executes before the first UI draw call. Because g_theme is a global pointer, direct field modifications take effect immediately across all subsequent drawing operations.
This approach is ideal for developers creating custom builds or testing color schemes iteratively without waiting for full recompilation cycles.
Method 3: JSON Configuration Files
ArmorPaint supports external theme overrides through JSON configuration files such as base/project.js or generated krom settings. Add entries mapping theme field names to hex or integer values, and the parsing code will populate g_theme during startup.
This method allows end users to customize their interface without accessing source code or recompiling, as the application reads these values at runtime before initializing the UI system.
Core UI Files That Reference Theme Values
The following source files in paint/sources/ui/ directly consume g_theme fields, determining how your customizations manifest visually:
ui_toolbar.c(lines 44-53) – ReadsHIGHLIGHT_COLfor toolbar backgrounds and temporarily mutatesELEMENT_H,BUTTON_H, andBUTTON_COLduring drawing operations.ui_sidebar.c(lines 18-20) – SwapsBUTTON_COLwithSEPARATOR_COLwhen rendering sidebar backgrounds, then restores the original value.ui_view2d.c(lines 379-382) – AppliesWINDOW_BG_COLandSEPARATOR_COLto the 2D viewport interface.ui_nodes.c(lines 108-112) – CustomizesBUTTON_COLandSHADOWSflags specifically for the node editor's search interface.ui_menubar.c(lines 98-102) – Handles menubar background rendering and highlight states using theme colors.ui_menu.c(lines 40-45) – Temporarily disablesFILL_BUTTON_BGand adjusts element heights when drawing dropdown menus.
Practical Implementation Examples
The following code snippets demonstrate how to implement each customization method in practice.
Hard-Coding a Dark Theme in main.c
This example overrides the default theme immediately after UI initialization to create a high-contrast dark interface with gold accents:
/* After engine and UI initialization */
g_theme->WINDOW_BG_COL = 0xff181818; // Deep charcoal background
g_theme->SEPARATOR_COL = 0xff404040; // Subtle separators
g_theme->HIGHLIGHT_COL = 0xffffd700; // Gold highlights
g_theme->ELEMENT_H = 34; // Larger touch targets
g_theme->BUTTON_H = g_theme->ELEMENT_H;
g_theme->BUTTON_COL = g_theme->WINDOW_BG_COL;
g_theme->FILL_BUTTON_BG = true;
g_theme->SHADOWS = false; // Flat design aesthetic
Loading Colors from JSON Configuration
Define your theme in a configuration file (e.g., ui_config.json):
{
"window_bg_col": "0xff181818",
"separator_col": "0xff404040",
"highlight_col": "0xffffd700",
"element_h": 34,
"fill_button_bg": true,
"shadows": false
}
Parse these values during application startup:
/* After parsing JSON data */
if (json_has(data, "window_bg_col"))
g_theme->WINDOW_BG_COL = json_get_u32(data, "window_bg_col");
if (json_has(data, "separator_col"))
g_theme->SEPARATOR_COL = json_get_u32(data, "separator_col");
if (json_has(data, "highlight_col"))
g_theme->HIGHLIGHT_COL = json_get_u32(data, "highlight_col");
if (json_has(data, "element_h"))
g_theme->ELEMENT_H = json_get_i32(data, "element_h");
g_theme->BUTTON_H = g_theme->ELEMENT_H;
if (json_has(data, "fill_button_bg"))
g_theme->FILL_BUTTON_BG = json_get_bool(data, "fill_button_bg");
if (json_has(data, "shadows"))
g_theme->SHADOWS = json_get_bool(data, "shadows");
Temporary Runtime Color Override
For contextual UI changes within specific drawing routines, save and restore theme values:
// Inside a custom node drawing function
u32 original_color = g_theme->BUTTON_COL; // Preserve current theme
g_theme->BUTTON_COL = 0xff0066ff; // Apply temporary blue
ui_draw_button(...); // Draw with custom color
g_theme->BUTTON_COL = original_color; // Restore global theme
Summary
- ArmorPaint theming centers on the global
g_themestructure defined in the Kinc UI layer and accessed throughoutpaint/sources/ui/. - Key customizable parameters include
WINDOW_BG_COL,HIGHLIGHT_COL,ELEMENT_H,BUTTON_H, and boolean flags likeSHADOWSandFILL_BUTTON_BG. - Three implementation strategies exist: editing source code in
util_ui.cfor permanent changes, patching values inmain.cfor runtime overrides, and loading external JSON configurations for user-level customization. - Critical files consuming theme data include
ui_toolbar.c,ui_sidebar.c,ui_view2d.c, andui_nodes.c, each referencing specificg_themefields to determine rendering behavior.
Frequently Asked Questions
Where is the theme configuration stored in ArmorPaint?
The theme configuration resides in the global g_theme struct, typically initialized in paint/sources/util/util_ui.c or the Kinc UI startup routine, with runtime usage distributed across files in paint/sources/ui/ such as ui_toolbar.c and ui_sidebar.c.
Do I need to rebuild ArmorPaint to change UI colors?
No. While editing defaults in the source code requires recompilation, you can override colors at runtime by modifying g_theme fields in main.c before the UI renders, or by loading a JSON configuration file that the application parses into the theme structure on startup.
What is the easiest way to modify UI element sizes?
Adjust the ELEMENT_H field in g_theme, which controls the standard height for most interface components. Remember to also update BUTTON_H to match if you want consistent button sizing, as seen in the source code where these values are通常 assigned together.
Can I change themes dynamically while ArmorPaint is running?
Yes. Because g_theme is a global structure accessed during every draw call, modifications to its fields take effect immediately without restarting the application. You can temporarily override values for specific drawing operations (such as changing a button color for a single frame) then restore the original values, as demonstrated in ui_sidebar.c when it swaps BUTTON_COL with SEPARATOR_COL during sidebar rendering.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →