Files
UsdLayerManager/src/ui/ViewportPanel.h
T
indigo f7a2262e80 Add multi-select, specifier column, and visibility shortcuts to hierarchy panel
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>
2026-07-02 07:04:22 +08:00

156 lines
8.6 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);
/// 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 (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;
pxr::UsdTimeCode m_displayTime = pxr::UsdTimeCode::Default();
pxr::UsdTimeCode m_editTime = pxr::UsdTimeCode::Default();
};
} // namespace UsdLayerManager