UsdLayerManager/openspec/changes/multi-viewport-support/tasks.md

47 lines
4.5 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

## 1. Extract ViewportTile class
- [x] 1.1 Create `src/ui/ViewportTile.h` with class declaration — owns `ViewportCamera`, `UsdSceneRenderer`, per-tile settings (grid, AA, bbox mode, bg color, render delegate, camera index), and a pointer to the shared selection + manipulator
- [x] 1.2 Create `src/ui/ViewportTile.cpp` — extract per-tile rendering logic from `ViewportPanel::Render()`: camera resolution, scene rendering, overlay rendering (axis, bbox, camera wireframes), DrawSelectionRect, RenderManipulatorOverlay, RenderContextMenu, HandleInput
- [x] 1.3 Verify tile renders standalone by temporarily instantiating one ViewportTile in Application
## 2. Refactor ViewportPanel into container
- [x] 2.1 Rewrite `ViewportPanel` header to own `std::vector<std::unique_ptr<ViewportTile>>`, `TransformManipulator`, shared selection state (`m_selectedSdfPaths`, `m_selectedPrimPath`), layout enum (`LayoutMode`), divider normalized positions, and maximize state (`m_maximizedTileIndex`, `m_layoutBeforeMaximize`)
- [x] 2.2 Rewrite `ViewportPanel::Render()` to compute tile rectangles from layout state, iterate tiles calling `ViewportTile::Render()` + `ViewportTile::HandleInput()`, and draw dividers. When maximized, render only the maximized tile at full viewport area (no dividers)
- [x] 2.3 Add `ViewportPanel::SetLayout(LayoutMode)` — creates/destroys tiles as needed, preserves focused tile's camera/settings when possible. Clear `m_maximizedTileIndex` on explicit layout change
- [x] 2.4 Add divider-drag handling in `ViewportPanel::Render()` — hit-test divider regions, update normalized positions on drag. Skip divider hit-test when maximized
- [x] 2.5 Add `ViewportPanel::SetLayoutMenu()` — a layout menu in the viewport title bar or right-click context menu
- [x] 2.6 Add Space-key maximize/restore: detect Space key press (guarded by `!io.WantTextInput` and `LayoutMode != Single`), save pre-maximize layout, set `m_maximizedTileIndex` to the hovered tile's index. On second Space or Escape, restore `m_maximizedTileIndex` to -1 and reload saved layout. Add visual indicator (border glow or text label) on maximized tile
- [x] 2.7 Expose `ViewportPanel::GetFocusedTileIndex()` and wire up `OnPrimPicked` / `OnPrimsPickedRect` from the focused tile to the shared selection callbacks. When maximized, the maximized tile is implicitly the focused tile
## 3. Implement shared selection
- [x] 3.1 Store `m_selectedSdfPaths` and `m_selectedPrimPath` on `ViewportPanel` (container)
- [x] 3.2 On pick in any tile, update shared selection, then broadcast `m_renderer.SetSelectedPaths()` to all tiles
- [x] 3.3 Fire `OnPrimPicked` / `OnPrimsPickedRect` from the container (not tiles) so downstream panels see a single source of truth
## 4. Implement focused-viewport manipulator
- [x] 4.1 Track `m_focusedTileIndex` on `ViewportPanel` — updated on LMB click in any tile
- [x] 4.2 Only call `m_manipulator.Render()` and `m_manipulator.HandleInput()` for the focused tile
- [x] 4.3 Wire keyboard shortcuts (Q/W/E/R) through the container to the global manipulator, and F/A to the focused tile's camera. Ensure Space maximize toggle works correctly when a tile is focused (not consumed by manipulator)
## 5. Add per-tile compact toolbar
- [x] 5.1 Implement compact icon-only toolbar in `ViewportTile::RenderToolbar()` — camera selector + render delegate button + grid/AA/bbox icons, all 16×16 with tooltips
- [ ] 5.2 Add overflow handling: if toolbar exceeds tile width, collapse into a "..." dropdown menu
## 6. Wire up Application integration
- [x] 6.1 Update `Application::Initialize()``m_viewportPanel` still works, `SetStage` broadcasts to all tiles, `SetSelectedPrimPath` updates shared selection
- [x] 6.2 Update `Application::RenderUI()` — ensure the Viewport window renders correctly with the new container layout
- [ ] 6.3 Test all existing interaction flows: stage open/close, camera switching, selection sync, manipulator tools, context menu, frame shortcuts
## 7. Build and test
- [x] 7.1 Configure with `cmake --preset default`
- [x] 7.2 Build Release with `cmake --build build --config Release` — fix any compilation errors
- [x] 7.3 Install with `cmake --install build --config Release`
- [ ] 7.4 Run `App.exe` and visually verify: single viewport works, switch to HSplit/VSplit/Quad, camera independence, shared selection, manipulator in focused tile only, divider dragging, Space-key maximize/restore with correct layout preservation, Escape restore, maximize in Quad layout, Space no-op in Single layout
- [ ] 7.5 Run CTest: `ctest --test-dir build -C Release` — fix any test failures