#pragma once #include "ViewportTile.h" #include "TransformManipulator.h" #include "IconManager.h" #include "../core/CommandHistory.h" #include #include #include #include #include #include #include namespace UsdLayerManager { /// How many tiles the viewport area is divided into. enum class LayoutMode { Single, ///< 1 tile — full area HSplit, ///< 2 tiles side by side (left | right) VSplit, ///< 2 tiles top / bottom Quad, ///< 4 tiles in a 2×2 grid }; /// Multi-viewport container. /// /// Owns N ViewportTile instances, a shared TransformManipulator, and the /// authoritative selection state. Manages layout splitting, draggable /// dividers, and the Maya-style Space-key maximize / restore. class ViewportPanel { public: ViewportPanel(); ~ViewportPanel(); // ── Setup ──────────────────────────────────────────────────────────────── void SetStage(pxr::UsdStageRefPtr stage); void FrameScene(); void SetCommandHistory(CommandHistory* history); void SetIconManager(IconManager* icons); // ── Selection (called by SceneHierarchyPanel) ──────────────────────────── /// Set a single selected prim (clears any multi-selection). void SetSelectedPrimPath(const std::string& path); // ── Main render (called from Application::RenderUI) ────────────────────── void Render(); // ── Pick callbacks (wired by Application after construction) ───────────── std::function OnPrimPicked; std::function&)> OnPrimsPickedRect; // ── Forwarding accessors (delegate to focused tile) ────────────────────── ViewportCamera& GetCamera(); UsdSceneRenderer& GetRenderer(); // ── Layout ─────────────────────────────────────────────────────────────── void SetLayout(LayoutMode mode); LayoutMode GetLayout() const { return m_layout; } int GetFocusedTileIndex() const { return m_focusedTileIndex; } private: // ── Tile rect helper ───────────────────────────────────────────────────── struct TileRect { ImVec2 pos; ImVec2 size; }; std::vector ComputeTileRects(ImVec2 origin, ImVec2 total) const; // ── Render sub-functions ───────────────────────────────────────────────── /// Draws the global vertical left toolbar (layout buttons + tool mode buttons). /// Occupies a reserved strip of width kToolbarW on the left of the content area. void RenderGlobalLeftToolbar(ImVec2 contentPos, ImVec2 contentSize); void DrawDividers(ImVec2 origin, ImVec2 total); void HandleMaximizeInput(int hoveredTileIndex); /// Returns true when the mouse is currently over a divider hit-zone or a /// divider drag is already in progress. Used to suppress tile rect-selection /// when the user is resizing tiles. bool IsMouseOverDivider(ImVec2 origin, ImVec2 total) const; /// Width (px) of the reserved left toolbar strip. static constexpr float kToolbarW = 52.0f; // ── Selection management ───────────────────────────────────────────────── /// Push the current shared selection into every tile and the manipulator. void BroadcastSelection(); /// Update the focused tile index and update the gizmo's selected prim. void UpdateFocusTile(int idx); // ── Tile setup ─────────────────────────────────────────────────────────── /// (Re)create tiles so that exactly `count` tiles exist, reusing existing /// ones where possible to preserve camera/settings state. void EnsureTileCount(int count); /// Wire pick callbacks for tile at index `i`. void WireCallbacks(int i); // ── Tiles ──────────────────────────────────────────────────────────────── std::vector> m_tiles; // ── Shared manipulator ─────────────────────────────────────────────────── TransformManipulator m_manipulator; // ── Shared selection (authoritative) ──────────────────────────────────── pxr::SdfPathVector m_selectedSdfPaths; std::string m_selectedPrimPath; // ── Layout state ───────────────────────────────────────────────────────── LayoutMode m_layout = LayoutMode::Single; float m_splitH = 0.5f; ///< Horizontal divider (0–1); used by HSplit + Quad float m_splitV = 0.5f; ///< Vertical divider (0–1); used by VSplit + Quad // Divider drag state bool m_draggingDivH = false; ///< Dragging the vertical line (changes m_splitH) bool m_draggingDivV = false; ///< Dragging the horizontal line (changes m_splitV) // ── Maximize state ─────────────────────────────────────────────────────── int m_maximizedTileIndex = -1; ///< -1 = not maximised LayoutMode m_layoutBeforeMaximize = LayoutMode::Single; float m_splitHBefore = 0.5f; float m_splitVBefore = 0.5f; // ── Focus ──────────────────────────────────────────────────────────────── int m_focusedTileIndex = 0; // ── Shared dependencies forwarded to tiles ─────────────────────────────── pxr::UsdStageRefPtr m_stage; IconManager* m_iconManager = nullptr; CommandHistory* m_commandHistory = nullptr; }; } // namespace UsdLayerManager