Files
UsdLayerManager/src/ui/ViewportPanel.h
T
2026-06-03 09:00:11 +08:00

130 lines
6.8 KiB
C++
Raw 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.
#pragma once
#include "ViewportTile.h"
#include "TransformManipulator.h"
#include "IconManager.h"
#include "../core/CommandHistory.h"
#include <pxr/usd/usd/stage.h>
#include <pxr/usd/sdf/path.h>
#include <imgui.h>
#include <functional>
#include <memory>
#include <vector>
#include <string>
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<void(const std::string&)> OnPrimPicked;
std::function<void(const std::vector<std::string>&)> 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<TileRect> 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<std::unique_ptr<ViewportTile>> 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 (01); used by HSplit + Quad
float m_splitV = 0.5f; ///< Vertical divider (01); 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