yaze 0.3.2
Link to the Past ROM Editor
 
Loading...
Searching...
No Matches
YAZE ImGui Layout Designer

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

// In EditorManager or main menu
// Member variable
layout_designer::LayoutDesignerWindow layout_designer_;
// Initialize
layout_designer_.Initialize(&panel_manager_);
// Open from menu
if (ImGui::MenuItem(ICON_MD_DASHBOARD " Layout Designer")) {
layout_designer_.Open();
}
// Draw each frame
if (layout_designer_.IsOpen()) {
layout_designer_.Draw();
}
#define ICON_MD_DASHBOARD
Definition icons.h:517

Creating a Layout

  1. Open Designer: Tools > Layout Designer
  2. Create New Layout: File > New (Ctrl+N)
  3. Add Panels:
    • Drag panels from palette on the left
    • Drop into canvas to create dock splits
  4. Configure Properties:
    • Select panel to edit properties
    • Adjust visibility, flags, priority
  5. Preview: Layout > Preview Layout
  6. 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

// Programmatically create a layout
auto layout = LayoutDefinition::CreateEmpty("My Layout");
// Split root node horizontally
layout.root->Split(ImGuiDir_Left, 0.3f);
// Add panel to left side
LayoutPanel left_panel;
left_panel.panel_id = "dungeon.room_selector";
left_panel.display_name = "Room List";
left_panel.icon = ICON_MD_LIST;
layout.root->child_left->AddPanel(left_panel);
// Add panel to right side
LayoutPanel right_panel;
right_panel.panel_id = "dungeon.object_editor";
right_panel.display_name = "Object Editor";
right_panel.icon = ICON_MD_EDIT;
layout.root->child_right->AddPanel(right_panel);
// Validate
std::string error;
if (layout.Validate(&error)) {
// Export code or save to JSON
}
#define ICON_MD_EDIT
Definition icons.h:645
#define ICON_MD_LIST
Definition icons.h:1094

Example 2: Import Current Layout

// Import from running application
layout_designer_.ImportFromRuntime();
// Modify the imported layout
auto* panel = current_layout_->FindPanel("dungeon.palette_editor");
if (panel) {
panel->visible_by_default = false;
panel->priority = 50;
}
// Export updated layout
layout_designer_.ExportCode("new_layout.cc");

Example 3: Load from JSON

// Load saved layout
layout_designer_.LoadLayout("layouts/dungeon_expert.json");
// Preview in application
layout_designer_.PreviewLayout();
// Make adjustments...
// Save changes
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:

  1. Update the data model if needed (layout_definition.h)
  2. Add UI components to LayoutDesignerWindow
  3. Update code generation to support new features
  4. Add tests for data model and serialization
  5. 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.