308 lines
8.7 KiB
Markdown
308 lines
8.7 KiB
Markdown
# 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:**
|
|
```cpp
|
|
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:**
|
|
1. Settings loaded → Applied to card_registry on startup
|
|
2. User toggles sidebar → Callback saves state immediately
|
|
3. Next launch → Sidebar restores exact state
|
|
|
|
**Implementation:**
|
|
- `EditorManager::Initialize()` applies saved state (lines 503-508)
|
|
- Callbacks registered (lines 529-541):
|
|
- `SetSidebarStateChangedCallback` - Auto-saves on toggle
|
|
- `SetCategoryChangedCallback` - 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_rom` callback 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 of `InitializeEditorLayout()`
|
|
- Checks `IsEmulatorVisible()` before `current_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
|
|
|
|
```cpp
|
|
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.
|
|
|