8.3 KiB
Editor System Refactoring - Complete Summary
Date: 2025-11-27
Status: ✅ Phase 1 & 2 Complete
Build Status: ✅ Full app compiles successfully
Overview
Completed incremental refactoring of the editor manager and UI system focusing on:
- Phase 1: Layout initialization and reset reliability
- Phase 2: Sidebar UX improvements and state persistence
Phase 1: Layout Initialization/Reset
Objectives
- Fix layout reset not properly rebuilding dockspaces
- Ensure emulator layout initializes correctly
- Add rebuild flag system for deferred layout updates
Key Changes
1. RebuildLayout() Method (layout_manager.h + .cc)
- Forces layout rebuild even if already initialized
- Validates dockspace exists before building
- Tracks last dockspace ID and editor type
- Duplicates InitializeEditorLayout logic but clears flags first
2. Rebuild Flag Integration (editor_manager.cc)
- Update() loop checks
IsRebuildRequested() - Validates ImGui frame scope before rebuilding
- Determines correct editor type (Emulator or current)
- Auto-clears flag after rebuild
3. Emulator Layout Trigger (editor_manager.cc)
SwitchToEditor(kEmulator)triggersInitializeEditorLayout- Frame validation ensures ImGui context ready
- Layout built with 7 emulator cards docked properly
4. Emulator in Sidebar (editor_manager.cc)
- "Emulator" added to active_categories when visible
- Emulator cards appear in sidebar alongside other editors
Coverage: All 11 Editor Types
| Editor | Build Method | Status |
|---|---|---|
| Overworld | BuildOverworldLayout | ✅ |
| Dungeon | BuildDungeonLayout | ✅ |
| Graphics | BuildGraphicsLayout | ✅ |
| Palette | BuildPaletteLayout | ✅ |
| Screen | BuildScreenLayout | ✅ |
| Music | BuildMusicLayout | ✅ |
| Sprite | BuildSpriteLayout | ✅ |
| Message | BuildMessageLayout | ✅ |
| Assembly | BuildAssemblyLayout | ✅ |
| Settings | BuildSettingsLayout | ✅ |
| Emulator | BuildEmulatorLayout | ✅ |
Phase 2: Sidebar UX Improvements
Issues Addressed
- Sidebar state didn't persist (always started collapsed)
- Expand button in menu bar (inconsistent with collapse button position)
- No visual feedback for active category
- Categories didn't show enabled/disabled state
- Layout offset broken when sidebar collapsed
- Menu bar could overflow with no indication
Key Changes
1. State Persistence (user_settings.h/cc, editor_manager.cc)
// Added to UserSettings::Preferences
bool sidebar_collapsed = false;
bool sidebar_tree_view_mode = true;
std::string sidebar_active_category;
- Auto-saves on every toggle/switch via callbacks
- Restored on app startup
2. Fixed Expand Button (editor_card_registry.cc)
- Collapsed sidebar shows 16px thin strip
- Expand button at same position as collapse button
- Both sidebars (icon + tree) have symmetric behavior
3. Category Enabled States (editor_card_registry.h/cc)
- Categories requiring ROM grayed out (40% opacity)
- Tooltip: "📁 Open a ROM first | Use File > Open ROM..."
- Emulator always enabled (doesn't require ROM)
- Click disabled category → No action
4. Enhanced Visual Feedback
- Active category: 4px accent bar, 90% accent button color
- Inactive category: 50% opacity, 130% brightness on hover
- Disabled category: 30% opacity, minimal hover
- Rich tooltips: Icon + name + status + shortcuts
5. Fixed Layout Offset (editor_manager.h)
GetLeftLayoutOffset() {
if (collapsed) return 16.0f; // Reserve strip space
return tree_mode ? 200.0f : 48.0f;
}
- Dockspace no longer overlaps collapsed sidebar
- Right panel interaction doesn't break sidebar
6. Responsive Menu Bar (ui_coordinator.cc)
- Progressive hiding: Version → Session → Dirty
- Notification bell shows hidden elements in tooltip
- Bell always visible as fallback information source
Architecture Improvements
Callback System
Pattern: User Action → UI Component → Callback → Save Settings
Callbacks Added:
card_registry_.SetSidebarStateChangedCallback((collapsed, tree_mode) → Save);
card_registry_.SetCategoryChangedCallback((category) → Save);
card_registry_.SetShowEmulatorCallback(() → ShowEmulator);
card_registry_.SetShowSettingsCallback(() → ShowSettings);
card_registry_.SetShowCardBrowserCallback(() → ShowCardBrowser);
Layout Rebuild Flow
Menu "Reset Layout"
→ OnResetWorkspaceLayout() queued as deferred action
→ EditorManager::ResetWorkspaceLayout()
→ ClearInitializationFlags()
→ RequestRebuild()
→ RebuildLayout(type, dockspace_id) // Immediate if in frame
→ Next Update(): Checks rebuild_requested_ flag
→ RebuildLayout() if not done yet
→ ClearRebuildRequest()
Multi-Session Coordination
Sidebar State: Global (not per-session)
- UI preference persists across all sessions
- Switching sessions doesn't change sidebar layout
Categories Shown: Session-aware
- Active editors contribute categories
- Emulator adds "Emulator" when visible
- Multiple sessions can show different categories
Files Modified
| File | Phase 1 | Phase 2 | Lines Changed |
|---|---|---|---|
| layout_manager.h | ✅ | +15 | |
| layout_manager.cc | ✅ | +132 | |
| editor_manager.h | ✅ | ✅ | +8 |
| editor_manager.cc | ✅ | ✅ | +55 |
| editor_card_registry.h | ✅ | +25 | |
| editor_card_registry.cc | ✅ | +95 | |
| user_settings.h | ✅ | +5 | |
| user_settings.cc | ✅ | +12 | |
| ui_coordinator.h | ✅ | +3 | |
| ui_coordinator.cc | ✅ | +50 |
Total: 10 files, ~400 lines of improvements
Testing Verification
Compilation
✅ Full app builds successfully (zero errors)
✅ Editor library builds independently
✅ All dependencies resolve correctly
Integration Points Verified
✅ Layout reset works for all 11 editor types
✅ Emulator layout initializes on first open
✅ Emulator layout resets properly
✅ Sidebar state persists across launches
✅ Sidebar doesn't overlap/conflict with right panel
✅ Category enabled states work correctly
✅ Menu bar responsive behavior functions
✅ Callbacks trigger and save without errors
User Experience Before/After
Layout Reset
Before:
- Inconsistent - sometimes worked, sometimes didn't
- Emulator layout ignored
- No fallback mechanism
After:
- Reliable - uses RebuildLayout() to force reset
- Emulator layout properly handled
- Deferred rebuild if not in valid frame
Sidebar Interaction
Before:
- Always started collapsed
- Expand button in menu bar (far from collapse)
- No visual feedback for active category
- All categories always enabled
- Sidebar disappeared when right panel opened
After:
- Starts in saved state (default: expanded, tree view)
- Expand button in same spot as collapse (16px strip)
- 4px accent bar shows active category
- ROM-requiring categories grayed out with helpful tooltips
- Sidebar reserves 16px even when collapsed (no disappearing)
Menu Bar
Before:
- Could overflow with no indication
- All elements always shown regardless of space
After:
- Progressive hiding when tight: Version → Session → Dirty
- Hidden elements shown in notification bell tooltip
- Bell always visible as info source
Known Limitations & Future Work
Not Implemented (Deferred)
- Sidebar collapse/expand animation
- Category priority/ordering system
- Collapsed sidebar showing vertical category icons
- Dockspace smooth resize on view mode toggle
Phase 3 Scope (Next)
- Agent chat widget integration improvements
- Proposals panel update notifications
- Unified panel toggle behavior
Phase 4 Scope (Future)
- ShortcutRegistry as single source of truth
- Shortcut conflict detection
- Visual shortcut cheat sheet
Summary
Phase 1 + 2 Together Provide:
- ✅ Reliable layout management across all editors
- ✅ Professional sidebar UX matching VSCode
- ✅ State persistence for user preferences
- ✅ Clear visual feedback and enabled states
- ✅ Responsive design adapting to space constraints
- ✅ Proper emulator integration throughout
Architecture Quality:
- Clean callback architecture for state management
- Proper separation of concerns (UI vs persistence)
- Defensive coding (frame validation, null checks)
- Comprehensive logging for debugging
Ready for production use and Phase 3 development.