8.7 KiB
Phase 2 Sidebar Fixes - Complete Implementation
Date: 2025-11-27
Status: ✅ Complete
Build Status: ✅ Compiles successfully (editor library verified)
Overview
Fixed critical sidebar UX issues based on user feedback:
- Sidebar state persistence
- Fixed expand button positioning
- Category enabled/disabled states
- Enhanced visual feedback and tooltips
- Improved emulator layout handling
- Fixed sidebar stuck issues with right panel interaction
Changes Implemented
1. Sidebar State Persistence
Files: user_settings.h, user_settings.cc, editor_manager.cc
Added to UserSettings::Preferences:
bool sidebar_collapsed = false; // Start expanded
bool sidebar_tree_view_mode = true; // Start in tree view
std::string sidebar_active_category; // Last active category
Flow:
- Settings loaded → Applied to card_registry on startup
- User toggles sidebar → Callback saves state immediately
- Next launch → Sidebar restores exact state
Implementation:
EditorManager::Initialize()applies saved state (lines 503-508)- Callbacks registered (lines 529-541):
SetSidebarStateChangedCallback- Auto-saves on toggleSetCategoryChangedCallback- Auto-saves on category switch
2. Fixed Expand Button Position
File: editor_card_registry.cc
Problem: Expand button was in menu bar, collapse button in sidebar (inconsistent UX)
Solution: Added collapsed sidebar strip UI (lines 580-625, 1064-1114)
- When collapsed: Draw 16px thin strip at sidebar edge
- Expand button positioned at same location as collapse button would be
- Click strip button to expand
- Menu bar toggle still works as secondary method
User Experience:
- ✅ Collapse sidebar → Button appears in same spot
- ✅ Click to expand → Sidebar opens smoothly
- ✅ No hunting for expand button in menu bar
3. Fixed Layout Offset Calculation
File: editor_manager.h
Problem: Collapsed sidebar returned 0.0f offset, causing dockspace to overlap
Solution: Return GetCollapsedSidebarWidth() (16px) when collapsed (lines 95-113)
Fixed:
- ✅ Sidebar strip always reserves 16px
- ✅ Dockspace doesn't overlap collapsed sidebar
- ✅ Right panel interaction no longer causes sidebar to disappear
4. Category Enabled/Disabled States
Files: editor_card_registry.h, editor_card_registry.cc, editor_manager.cc
Added:
has_romcallback parameter to DrawSidebar / DrawTreeSidebar- Enabled check:
rom_loaded || category == "Emulator" - Visual: 40% opacity + disabled hover for categories requiring ROM
Icon View (DrawSidebar):
- Disabled categories: Grayed out, very subtle hover
- Tooltip shows: "🟡 Overworld Editor | ─── | 📁 Open a ROM first"
- Click does nothing when disabled
Tree View (DrawTreeSidebar):
- Disabled categories: 40% opacity
- Enhanced tooltip with instructions: "Open a ROM first | Use File > Open ROM to load a ROM file"
- Tree node not selectable/clickable when disabled
5. Enhanced Visual Feedback
File: editor_card_registry.cc
Category Buttons:
- Active indicator bar: 4px width (was 2px), no rounding for crisp edge
- Active button: 90% accent opacity, 100% on hover
- Inactive button: 50% opacity, 130% brightness on hover
- Disabled button: 30% opacity, minimal hover
Tooltips (Rich Formatting):
Icon View Category:
🗺 Overworld Editor
─────────────────
Click to switch to Overworld view
✓ Currently Active
Disabled Category:
🟡 Overworld Editor
─────────────────
📁 Open a ROM first
Icon View Card:
🗺 Overworld Canvas
─────────────────
Ctrl+Shift+O
👁 Visible
6. Fixed Emulator Layout Handling
File: editor_manager.cc
Reset Workspace Layout (lines 126-146):
- Now uses
RebuildLayout()instead ofInitializeEditorLayout() - Checks
IsEmulatorVisible()beforecurrent_editor_ - Validates ImGui frame scope before rebuilding
- Falls back to deferred rebuild if not in frame
Switch to Emulator (lines 1908-1930):
- Validates ImGui context before initializing layout
- Checks
IsLayoutInitialized()before initializing - Logs confirmation of layout initialization
Update Loop (lines 653-675):
- Checks
IsRebuildRequested()flag - Determines correct editor type (Emulator takes priority)
- Executes rebuild and clears flag
Behavioral Changes
Sidebar Lifecycle
Before:
Start: Always collapsed, tree mode
Toggle: No persistence
Restart: Always collapsed again
After:
Start: Reads from settings (default: expanded, tree mode)
Toggle: Auto-saves immediately
Restart: Restores exact previous state
Category Switching
Before:
Multiple editors open → Sidebar auto-switches → User confused
No visual feedback → Unclear which category is active
After:
User explicitly selects category → Stays on that category
4px accent indicator bar → Clear active state
Enhanced tooltips → Explains what each category does
Disabled categories → Grayed out with helpful "Open ROM first" message
Emulator Integration
Before:
Open emulator → Layout not initialized → Cards floating
Reset layout → Doesn't affect emulator properly
After:
Open emulator → Layout initializes with proper docking
Reset layout → Correctly rebuilds emulator layout
Emulator category → Shows in sidebar when emulator visible
User Workflow Improvements
Opening Editor Without ROM
Before:
1. Start app (no ROM)
2. Sidebar shows placeholder with single "Open ROM" button
3. Categories not visible
After:
1. Start app (no ROM)
2. Sidebar shows all categories (grayed out except Emulator)
3. Hover category → "📁 Open a ROM first"
4. Clear visual hierarchy of what's available vs requires ROM
Collapsing Sidebar
Before:
1. Click collapse button in sidebar
2. Sidebar disappears
3. Hunt for expand icon in menu bar
4. Click menu icon to expand
5. Button moved - have to find collapse button again
After:
1. Click collapse button (bottom of sidebar)
2. Sidebar shrinks to 16px strip
3. Expand button appears in same spot
4. Click to expand
5. Collapse button right where expand button was
Switching Between Editors
Before:
Open Overworld → Category switches to "Overworld"
Open Dungeon → Category auto-switches to "Dungeon"
Want to see Overworld cards while Dungeon is active? Can't.
After:
Open Overworld → Category stays on user's selection
Open Dungeon → Category stays on user's selection
Want to see Overworld cards? Click Overworld category button
Clear visual feedback: Active category has 4px accent bar
Technical Implementation
Callback Architecture
User Action → UI Component → Callback → Save Settings
Examples:
- Click collapse → ToggleSidebarCollapsed() → on_sidebar_state_changed_() → Save()
- Switch category → SetActiveCategory() → on_category_changed_() → Save()
- Toggle tree mode → ToggleTreeViewMode() → on_sidebar_state_changed_() → Save()
Layout Offset Calculation
GetLeftLayoutOffset() {
if (!sidebar_visible) return 0.0f;
if (collapsed) return 16.0f; // Strip width
return tree_mode ? 200.0f : 48.0f; // Full width
}
Impact:
- Dockspace properly reserves space for sidebar strip
- Right panel interaction doesn't cause overlap
- Smooth resizing when toggling modes
Emulator as Category
Registration: Lines 298-364 in editor_manager.cc
- Emulator cards registered with category="Emulator"
- Cards: CPU Debugger, PPU Viewer, Memory, etc.
Sidebar Integration: Lines 748-752 in editor_manager.cc
- When
IsEmulatorVisible()→ Add "Emulator" to active_categories - Emulator doesn't require ROM (always enabled)
- Layout initializes on first switch to emulator
Verification
✅ Compilation: Editor library builds successfully
✅ State Persistence: Settings save/load correctly
✅ Visual Feedback: Enhanced tooltips with color coordination
✅ Category Enabled States: ROM-requiring categories properly disabled
✅ Layout System: Emulator layout initializes and resets correctly
✅ Offset Calculation: Sidebar strip reserves proper space
Summary
All Phase 2 fixes complete:
- ✅ Sidebar state persists across sessions
- ✅ Expand button at fixed position (not in menu bar)
- ✅ Categories show enabled/disabled state
- ✅ Enhanced tooltips with rich formatting
- ✅ Improved category switching visual feedback
- ✅ Emulator layout properly initializes and resets
- ✅ Sidebar doesn't get stuck with right panel interaction
Result: VSCode-like sidebar experience with professional UX and persistent state.