A WYSIWYG (What You See Is What You Get) visual designer for creating and managing ImGui panel layouts in the yaze application.
Overview
The Layout Designer provides a visual interface for designing complex multi-panel layouts without writing DockBuilder code. It addresses the growing complexity of managing 15+ editor panels across multiple categories.
Features
Current (Phase 1)
- ✅ Data model for layouts (panels, dock nodes, splits)
- ✅ Basic UI structure (palette, canvas, properties)
- ✅ Panel drag-and-drop from palette
- ✅ Visual dock node rendering
- ✅ Code generation preview (DockBuilder + LayoutPresets)
- ✅ Layout validation
Planned
- ⏳ JSON import/export
- ⏳ Runtime layout import (from current application state)
- ⏳ Live preview (apply to application)
- ⏳ Interactive split ratio adjustment
- ⏳ Undo/Redo support
- ⏳ Layout tree view with drag-to-reorder
- ⏳ Panel search and filtering
Quick Start
Opening the Designer
layout_designer::LayoutDesignerWindow layout_designer_;
layout_designer_.Initialize(&panel_manager_);
layout_designer_.Open();
}
if (layout_designer_.IsOpen()) {
layout_designer_.Draw();
}
#define ICON_MD_DASHBOARD
Creating a Layout
- Open Designer: Tools > Layout Designer
- Create New Layout: File > New (Ctrl+N)
- Add Panels:
- Drag panels from palette on the left
- Drop into canvas to create dock splits
- Configure Properties:
- Select panel to edit properties
- Adjust visibility, flags, priority
- Preview: Layout > Preview Layout
- Export Code: File > Export Code
Example Generated Code
DockBuilder Code:
void LayoutManager::BuildDungeonExpertLayout(ImGuiID dockspace_id) {
ImGui::DockBuilderRemoveNode(dockspace_id);
ImGui::DockBuilderAddNode(dockspace_id, ImGuiDockNodeFlags_DockSpace);
ImGuiID dock_main_id = dockspace_id;
ImGuiID dock_left_id = ImGui::DockBuilderSplitNode(
dock_main_id, ImGuiDir_Left, 0.25f, nullptr, &dock_main_id);
ImGui::DockBuilderDockWindow("Room List", dock_left_id);
ImGui::DockBuilderDockWindow("Object Editor", dock_main_id);
ImGui::DockBuilderFinish(dockspace_id);
}
Layout Preset:
PanelLayoutPreset LayoutPresets::GetDungeonExpertPreset() {
return {
.name = "Dungeon Expert",
.description = "Optimized for advanced dungeon editing",
.editor_type = EditorType::kDungeon,
.default_visible_panels = {
"dungeon.room_selector",
"dungeon.object_editor",
},
.panel_positions = {
{"dungeon.room_selector", DockPosition::Left},
{"dungeon.object_editor", DockPosition::Center},
}
};
}
Architecture
Data Model
LayoutDefinition
├── metadata (name, author, version, timestamps)
├── canvas_size
└── root: DockNode
├── type (Root/Split/Leaf)
├── split configuration (direction, ratio)
├── children (for splits)
└── panels (for leaves)
├── panel_id
├── display_name
├── icon
├── flags (closable, pinnable, etc.)
└── properties (size, priority, etc.)
Components
- LayoutDesignerWindow: Main window coordinator
- LayoutDefinition: Data model for complete layout
- DockNode: Hierarchical dock structure
- LayoutPanel: Panel configuration and metadata
Usage Examples
Example 1: Simple Two-Panel Layout
auto layout = LayoutDefinition::CreateEmpty("My Layout");
layout.root->Split(ImGuiDir_Left, 0.3f);
LayoutPanel left_panel;
left_panel.panel_id = "dungeon.room_selector";
left_panel.display_name = "Room List";
layout.root->child_left->AddPanel(left_panel);
LayoutPanel right_panel;
right_panel.panel_id = "dungeon.object_editor";
right_panel.display_name = "Object Editor";
layout.root->child_right->AddPanel(right_panel);
std::string error;
if (layout.Validate(&error)) {
}
Example 2: Import Current Layout
layout_designer_.ImportFromRuntime();
auto* panel = current_layout_->FindPanel("dungeon.palette_editor");
if (panel) {
panel->visible_by_default = false;
panel->priority = 50;
}
layout_designer_.ExportCode("new_layout.cc");
Example 3: Load from JSON
layout_designer_.LoadLayout("layouts/dungeon_expert.json");
layout_designer_.PreviewLayout();
layout_designer_.SaveLayout("layouts/dungeon_expert_v2.json");
JSON Format
Layouts can be saved as JSON for version control and sharing:
{
"layout": {
"name": "Dungeon Expert",
"version": "1.0.0",
"editor_type": "Dungeon",
"root_node": {
"type": "split",
"direction": "horizontal",
"ratio": 0.3,
"left": {
"type": "leaf",
"panels": [
{
"id": "dungeon.room_selector",
"display_name": "Room List",
"icon": "ICON_MD_LIST",
"visible_by_default": true,
"priority": 20
}
]
},
"right": {
"type": "leaf",
"panels": [
{
"id": "dungeon.object_editor",
"display_name": "Object Editor",
"priority": 30
}
]
}
}
}
}
Benefits
For Developers
- ⚡ Faster iteration: Design layouts visually, no compile cycle
- 🐛 Fewer bugs: See layout immediately, catch issues early
- 📊 Better organization: Visual understanding of complex layouts
- ✨ Consistent code: Generated code follows best practices
For Users
- 🎨 Customizable workspace: Create personalized layouts
- 💾 Save/load layouts: Switch between workflows easily
- 🤝 Share layouts: Import community layouts
- 🎯 Better UX: Optimized panel arrangements
For AI Agents
- 🤖 Programmatic control: Generate layouts from descriptions
- 🎯 Task-specific layouts: Optimize for specific agent tasks
- 📝 Reproducible environments: Save agent workspace state
Development Status
Current Phase: Phase 1 - Core Infrastructure ✅
Next Phase: Phase 2 - JSON Serialization
See Architecture Doc for complete implementation plan.
Contributing
When adding new features to the Layout Designer:
- Update the data model if needed (
layout_definition.h)
- Add UI components to
LayoutDesignerWindow
- Update code generation to support new features
- Add tests for data model and serialization
- Update this README with examples
Testing
# Build with layout designer
cmake -B build -DYAZE_BUILD_LAYOUT_DESIGNER=ON
cmake --build build
# Run tests
./build/test/layout_designer_test
Troubleshooting
Q: Designer window doesn't open
- Check that
Initialize() was called with valid PanelManager
- Ensure
Draw() is called every frame when IsOpen() is true
Q: Panels don't appear in palette
- Verify panels are registered with PanelManager
- Check
GetAvailablePanels() implementation
Q: Generated code doesn't compile
- Validate layout before exporting (
Layout > Validate)
- Check panel IDs match registered panels
- Ensure all nodes have valid split ratios (0.0 to 1.0)
References
License
Same as yaze project license.