f7a2262e80
Ctrl+click toggles prim selection; Shift+click range-selects using a per-frame visible-order list. Multi-selection is broadcast to the viewport via a new SetOnPrimsSelected callback so Hydra highlights all selected prims. Adds a 5th table column showing each prim's SdfSpecifier (def/over/class) with colour coding. 'over' prims are shown in orange to make overrides immediately visible. Visibility icon updated: invisible prims show EyeSlash in orange instead of grey. Ctrl+H / Shift+H keyboard shortcuts hide / show all selected prims. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
156 lines
8.6 KiB
C++
156 lines
8.6 KiB
C++
#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);
|
||
|
||
/// Push timeline time codes to every tile and the shared manipulator.
|
||
/// displayTime — frame used for all evaluation (render, cameras, bboxes).
|
||
/// editTime — frame writes are authored at (Default unless Auto-Key).
|
||
void SetTimeCodes(pxr::UsdTimeCode displayTime, pxr::UsdTimeCode editTime);
|
||
|
||
// ── Selection (called by SceneHierarchyPanel) ────────────────────────────
|
||
/// Set a single selected prim (clears any multi-selection).
|
||
void SetSelectedPrimPath(const std::string& path);
|
||
/// Set multiple selected prims (from hierarchy Ctrl+click multi-select).
|
||
void SetSelectedPrimPaths(const std::vector<std::string>& paths);
|
||
|
||
// ── Main render (called from Application::RenderUI) ──────────────────────
|
||
void Render(bool* p_open = nullptr);
|
||
|
||
// ── 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; }
|
||
|
||
// ── Global preferences ────────────────────────────────────────────────────
|
||
/// Set render delegate on tiles that have no saved delegate yet (empty token).
|
||
/// Called once on startup so the pref default applies to fresh tiles.
|
||
void ApplyDefaultDelegate(const std::string& delegate);
|
||
/// Apply color correction to every tile (always global).
|
||
void ApplyGlobalColorCorrection(int ccMode, const std::string& ocioDisplay,
|
||
const std::string& ocioView,
|
||
const std::string& ocioColorSpace,
|
||
const std::string& ocioLook);
|
||
|
||
// ── Settings persistence ─────────────────────────────────────────────────
|
||
/// Load layout and per-tile render settings from a simple INI file.
|
||
void LoadSettings(const std::string& path);
|
||
/// Save current layout and per-tile render settings to a simple INI file.
|
||
void SaveSettings(const std::string& path) const;
|
||
|
||
|
||
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 = 40.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 (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;
|
||
pxr::UsdTimeCode m_displayTime = pxr::UsdTimeCode::Default();
|
||
pxr::UsdTimeCode m_editTime = pxr::UsdTimeCode::Default();
|
||
};
|
||
|
||
} // namespace UsdLayerManager
|