#pragma once #include "HierarchyModel.h" #include "Commands/EditorEditCommandRoute.h" #include #include #include #include #include #include #include #include #include #include namespace XCEngine::UI::Editor::App { class BuiltInIcons; class EditorSceneRuntime; class HierarchyPanel final : public EditorEditCommandRoute { public: enum class EventKind : std::uint8_t { None = 0, SelectionChanged, Reparented, MovedToRoot, RenameRequested }; struct Event { EventKind kind = EventKind::None; std::string itemId = {}; std::string targetItemId = {}; std::string label = {}; }; void Initialize(); void SetSceneRuntime(EditorSceneRuntime* sceneRuntime); void SetBuiltInIcons(const BuiltInIcons* icons); void ResetInteractionState(); void Update( const UIEditorPanelContentHostFrame& contentHostFrame, const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents, bool allowInteraction, bool panelActive); void Append(::XCEngine::UI::UIDrawList& drawList) const; bool WantsHostPointerCapture() const; bool WantsHostPointerRelease() const; bool HasActivePointerCapture() const; const std::vector& GetFrameEvents() const; UIEditorHostCommandEvaluationResult EvaluateEditCommand( std::string_view commandId) const override; UIEditorHostCommandDispatchResult DispatchEditCommand( std::string_view commandId) override; private: const UIEditorPanelContentHostPanelState* FindMountedHierarchyPanel( const UIEditorPanelContentHostFrame& contentHostFrame) const; void ResetTransientState(); void SyncModelFromScene(); void RebuildItems(); void ProcessDragAndFrameEvents( const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents, const ::XCEngine::UI::UIRect& bounds, bool allowInteraction, bool panelActive); const HierarchyNode* GetSelectedNode() const; void SyncTreeSelectionFromSceneRuntime(); void SyncSceneRuntimeSelectionFromTree(); void EmitSelectionEvent(); void EmitReparentEvent( EventKind kind, std::string itemId, std::string targetItemId); void EmitRenameRequestedEvent(std::string_view itemId); void ClearRenameState(); void QueueRenameSession(std::string_view itemId); bool TryStartQueuedRenameSession( const Widgets::UIEditorTreeViewLayout& layout); void UpdateRenameSession( const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents, const Widgets::UIEditorTreeViewLayout& layout); void SyncTreeFocusState( const std::vector<::XCEngine::UI::UIInputEvent>& inputEvents); ::XCEngine::UI::UIRect BuildRenameBounds( std::string_view itemId, const Widgets::UIEditorTreeViewLayout& layout) const; const BuiltInIcons* m_icons = nullptr; EditorSceneRuntime* m_sceneRuntime = nullptr; HierarchyModel m_model = {}; std::vector m_treeItems = {}; ::XCEngine::UI::Widgets::UISelectionModel m_treeSelection = {}; ::XCEngine::UI::Widgets::UIExpansionModel m_expansion = {}; UIEditorTreeViewInteractionState m_treeInteractionState = {}; UIEditorTreeViewInteractionFrame m_treeFrame = {}; UIEditorInlineRenameSessionState m_renameState = {}; UIEditorInlineRenameSessionFrame m_renameFrame = {}; std::string m_pendingRenameItemId = {}; std::vector m_frameEvents = {}; Collections::TreeDragDrop::State m_dragState = {}; bool m_visible = false; }; } // namespace XCEngine::UI::Editor::App