backend-infra-engineer: Post v0.3.9-hotfix7 snapshot (build cleanup)
This commit is contained in:
307
docs/internal/archive/completed_features/phase2-sidebar-fixes.md
Normal file
307
docs/internal/archive/completed_features/phase2-sidebar-fixes.md
Normal file
@@ -0,0 +1,307 @@
|
||||
# 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.
|
||||
|
||||
Reference in New Issue
Block a user