generates ImGui interfaces based on JSON schemas.
README
ofxImGuiJson
ofxImGuiJson is an openFrameworks addon that automatically generates ImGui interfaces based on JSON schemas. Simply define a JSON schema and the corresponding editable UI will be created automatically.
Features
- Schema-based UI Generation: Automatic UI generation based on JSON schemas
- Rich Data Type Support: boolean, int, float, string, object, array, numeric arrays
- Diverse UI Widgets: slider, drag, input, table, chips, collapsible, etc.
- Path-based Callbacks: Monitor changes to specific data paths
- Template-based Design: Compatible with various JSON libraries including nlohmann::json
- Constraint Support: Detailed control with minimum, maximum, speed parameters
Setup
Dependencies
- ofxImGui - openFrameworks version of ImGui
Installation
1. Clone into openFrameworks
addons folder: cd OF_ROOT/addons
git clone https://github.com/nariakiiwatani/ofxImGuiJson.git2. Add to your project's
addons.make: ofxImGui
ofxImGuiJson3. Include headers:
#include "ofxImGui.h"
include "ofxImGuiJson.h"
include <nlohmann/json.hpp>
Basic Usage
Quick Start
#include "ofApp.h"
class ofApp : public ofBaseApp {
ofxImGui::Gui gui;
nlohmann::json schema;
nlohmann::json data;
public:
void setup() override {
gui.setup();
// Define schema
schema = {
{"type", "object"},
{"properties", {
{"name", {{"type", "string"}, {"default", "John"}}},
{"age", {{"type", "int"}, {"minimum", 0}, {"maximum", 100}, {"default", 25}}}
}}
};
// Generate default data from schema
data = ofxImGuiJson::GenerateDefault(schema);
}
void draw() override {
gui.begin();
if (ImGui::Begin("Settings")) {
// Edit JSON data
ofxImGuiJson::Edit("Profile", data, &schema);
}
ImGui::End();
gui.end();
}
};Architecture
Component Structure
ofxImGuiJson/
├── src/
│ ├── ofxImGuiJson.h # Main API
│ ├── ofxImGuiJsonDispatcher.h # Editor dispatcher
│ ├── ofxImGuiJsonCallback.h # Callback system
│ └── Editors/
│ ├── ofxImGuiJsonPrimitiveEditor.h # Primitive type editor
│ ├── ofxImGuiJsonObjectEditor.h # Object type editor
│ ├── ofxImGuiJsonArrayEditor.h # Array type editor
│ └── ofxImGuiJsonNumericArrayEditor.h # Numeric array editorData Flow
1. Schema Analysis: Extract type information from JSON schema 2. Dispatch: Select appropriate editor based on data type 3. UI Generation: Generate corresponding ImGui components 4. Change Detection: Monitor value changes from user input 5. Callback Execution: Execute callbacks corresponding to changed paths
API Reference
Main Functions
Edit()
template<typename JsonType>
bool Edit(const char label, JsonType &data, const JsonType schema,
const CallbackList<JsonType> &callbacks = {})Main function to edit JSON data.
Parameters:
label: UI labeldata: JSON data to edit (reference)schema: JSON schema (pointer)callbacks: Callback list (optional)
bool:trueif data was changed
GenerateDefault()
template<typename JsonType>
JsonType GenerateDefault(const JsonType &schema)Generate default data from schema.
Parameters:
schema: JSON schema
JsonType: Generated default data
Schema Specification
Basic Structure
{
"type": "data_type",
"label": "UI_display_name",
"default": "default_value",
"ui:widget": "widget_type"
}Supported Types
1. Primitive Types
# Boolean
{
"type": "boolean",
"label": "Enable Feature",
"default": true
}# Integer
{
"type": "int",
"label": "Age",
"minimum": 0,
"maximum": 120,
"default": 25,
"ui:widget": "slider" // "drag", "input"
}# Float
{
"type": "float",
"label": "Height",
"minimum": 0.0,
"maximum": 250.0,
"speed": 0.1,
"default": 170.5,
"ui:widget": "drag" // "slider", "input"
}# String
{
"type": "string",
"label": "Name",
"default": "John Doe"
}2. Object Type
{
"type": "object",
"label": "Profile",
"ui:widget": "collapsible", // "inline"
"properties": {
"name": {"type": "string", "default": "John"},
"age": {"type": "int", "default": 25}
}
}Widgets:
"collapsible": Collapsible tree node"inline": Inline display
3. Array Type
{
"type": "array",
"label": "Items",
"ui:widget": "table", // "chips"
"items": {"type": "string", "default": "item"},
"minItems": 0,
"maxItems": 10,
"default": ["item1", "item2"]
}Widgets:
"table": Table format display"chips": Chip format display (recommended for string arrays)
4. Numeric Array Type
Fixed-size numeric arrays (for vectors, coordinates, etc.):
{
"type": "float", // or "int"
"label": "RGB Color",
"size": 3,
"minimum": 0.0,
"maximum": 1.0,
"ui:widget": "slider", // "drag", "input"
"default": [0.5, 0.5, 0.5]
}Callback System
Basic Usage
using namespace ofxImGuiJson;
CallbackList<nlohmann::json> callbacks = {
// Path-specific callback
{{"age"}, [](const std::string& path, const auto& oldVal, const auto& newVal) {
ofLogNotice("Changed") << "Path: " << path << ", New value: " << newVal;
}},
// Wildcard pattern
{{"profile/"}, [](const auto& newVal) {
ofLogNotice("Profile") << "Profile changed: " << newVal;
}},
// Regular expression pattern
{{std::regex(R"(scores\[\d+\])")}, []() {
ofLogNotice("Scores") << "Score array updated";
}}
};
// Edit with callbacks
ofxImGuiJson::Edit("Settings", data, &schema, callbacks);Path Patterns
1. Exact Match:
"name" - Matches exact path 2. Wildcard: "profile/" - Pattern matching 3. Regular Expression: std::regex(pattern) - Advanced pattern matchingCallback Function Formats
Supports various argument patterns:
// Full arguments
[](const std::string& path, const auto& oldVal, const auto& newVal) { ... }
// Path and new value only
[](const std::string& path, const auto& newVal) { ... }
// Path only
[](const std::string& path) { ... }
// Value change only
[](const auto& oldVal, const auto& newVal) { ... }
// New value only
[](const auto& newVal) { ... }
// No arguments
[]() { ... }Practical Examples
Game Settings UI
nlohmann::json gameSettings = {
{"type", "object"},
{"label", "Game Settings"},
{"ui:widget", "collapsible"},
{"properties", {
{"graphics", {
{"type", "object"},
{"label", "Graphics"},
{"properties", {
{"resolution", {
{"type", "int"},
{"size", 2},
{"label", "Resolution"},
{"default", {1920, 1080}}
}},
{"vsync", {
{"type", "boolean"},
{"label", "V-Sync"},
{"default", true}
}}
}}
}},
{"audio", {
{"type", "object"},
{"label", "Audio"},
{"properties", {
{"masterVolume", {
{"type", "float"},
{"label", "Master Volume"},
{"ui:widget", "slider"},
{"minimum", 0.0},
{"maximum", 1.0},
{"default", 0.8}
}}
}}
}}
}}
};
// Usage example
data = ofxImGuiJson::GenerateDefault(gameSettings);
// Monitor settings changes
CallbackList<nlohmann::json> settingsCallbacks = {
{{"graphics/vsync"}, [this](bool enabled) {
ofSetVerticalSync(enabled);
}},
{{"audio/masterVolume"}, [this](float volume) {
soundManager.setMasterVolume(volume);
}}
};
// UI rendering
ofxImGuiJson::Edit("Settings", data, &gameSettings, settingsCallbacks);Array Data Editing
nlohmann::json arraySchema = {
{"type", "array"},
{"label", "Enemy Spawn Points"},
{"ui:widget", "table"},
{"items", {
{"type", "object"},
{"properties", {
{"position", {
{"type", "float"},
{"size", 2},
{"label", "Position"},
{"default", {0.0, 0.0}}
}},
{"enemyType", {
{"type", "string"},
{"label", "Enemy Type"},
{"default", "basic"}
}}
}}
}},
{"minItems", 1},
{"maxItems", 20}
};Advanced Features
Custom Schema Extensions
Add custom UI control properties:
{
"type": "float",
"label": "Speed",
"ui:widget": "drag",
"ui:tooltip": "Movement speed in units per second",
"minimum": 0.0,
"maximum": 10.0,
"speed": 0.1,
"default": 5.0
}License
MIT License
Contributing
Pull requests and issue reports are welcome.
Related Projects
- ofxImGui - ImGui for openFrameworks
- nlohmann/json - Modern C++ JSON Library
- JSON Schema - JSON Schema Specification
ofxAddons