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

4.5 KiB
Raw Permalink Blame History

1. Extract ViewportTile class

  • 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
  • 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
  • 1.3 Verify tile renders standalone by temporarily instantiating one ViewportTile in Application

2. Refactor ViewportPanel into container

  • 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)
  • 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)
  • 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
  • 2.4 Add divider-drag handling in ViewportPanel::Render() — hit-test divider regions, update normalized positions on drag. Skip divider hit-test when maximized
  • 2.5 Add ViewportPanel::SetLayoutMenu() — a layout menu in the viewport title bar or right-click context menu
  • 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
  • 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

  • 3.1 Store m_selectedSdfPaths and m_selectedPrimPath on ViewportPanel (container)
  • 3.2 On pick in any tile, update shared selection, then broadcast m_renderer.SetSelectedPaths() to all tiles
  • 3.3 Fire OnPrimPicked / OnPrimsPickedRect from the container (not tiles) so downstream panels see a single source of truth

4. Implement focused-viewport manipulator

  • 4.1 Track m_focusedTileIndex on ViewportPanel — updated on LMB click in any tile
  • 4.2 Only call m_manipulator.Render() and m_manipulator.HandleInput() for the focused tile
  • 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

  • 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

  • 6.1 Update Application::Initialize()m_viewportPanel still works, SetStage broadcasts to all tiles, SetSelectedPrimPath updates shared selection
  • 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

  • 7.1 Configure with cmake --preset default
  • 7.2 Build Release with cmake --build build --config Release — fix any compilation errors
  • 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