#pragma once #include "EditorActions.h" #include "Commands/ComponentCommands.h" #include "ComponentEditors/ComponentEditorRegistry.h" #include "Core/EditorEvents.h" #include "Core/IEditorContext.h" #include "UI/PopupState.h" #include "UI/UI.h" #include namespace XCEngine { namespace Editor { namespace Actions { inline std::string BuildAddComponentMenuLabel(const IComponentEditor& editor, ::XCEngine::Components::GameObject* gameObject) { std::string label = editor.GetDisplayName(); if (Commands::CanAddComponent(editor, gameObject)) { return label; } const char* reason = editor.GetAddDisabledReason(gameObject); if (reason && reason[0] != '\0') { label += " ("; label += reason; label += ")"; } return label; } inline void HandleInspectorSelectionChanged( IEditorContext& context, const SelectionChangedEvent& event, uint64_t& selectedEntityId, UI::DeferredPopupState& addComponentPopup) { if (context.GetUndoManager().HasPendingInteractiveChange()) { context.GetUndoManager().FinalizeInteractiveChange(); } selectedEntityId = event.primarySelection; addComponentPopup.Clear(); } inline bool DrawInspectorAddComponentButton(UI::DeferredPopupState& addComponentPopup, bool enabled = true) { if (!DrawInspectorAction(MakeAddComponentButtonAction(enabled))) { return false; } addComponentPopup.RequestOpen(); return true; } inline bool DrawInspectorAddComponentMenu(IEditorContext& context, ::XCEngine::Components::GameObject* gameObject) { bool drewAnyEntry = false; for (const auto& editor : ComponentEditorRegistry::Get().GetEditors()) { if (!editor || !editor->ShowInAddComponentMenu()) { continue; } drewAnyEntry = true; const bool canAdd = Commands::CanAddComponent(*editor, gameObject); const std::string label = BuildAddComponentMenuLabel(*editor, gameObject); DrawMenuAction(MakeAddComponentMenuAction(label, canAdd), [&]() { if (Commands::AddComponent(context, *editor, gameObject)) { ImGui::CloseCurrentPopup(); } }); } return drewAnyEntry; } inline void DrawInspectorAddComponentPopup( IEditorContext& context, UI::DeferredPopupState& addComponentPopup, ::XCEngine::Components::GameObject* gameObject) { addComponentPopup.ConsumeOpenRequest("AddComponent"); if (!UI::BeginTitledPopup("AddComponent", "Components")) { return; } if (!DrawInspectorAddComponentMenu(context, gameObject)) { UI::DrawHintText("No registered component editors"); } UI::EndTitledPopup(); } inline bool DrawInspectorComponentMenu( IEditorContext& context, ::XCEngine::Components::Component* component, ::XCEngine::Components::GameObject* gameObject, const IComponentEditor* editor) { const bool canRemove = Commands::CanRemoveComponent(component, editor); return DrawMenuAction(MakeRemoveComponentAction(canRemove), [&]() { Commands::RemoveComponent(context, component, gameObject, editor); }); } inline void FinalizeInspectorInteractiveChangeIfIdle(IEditorContext& context) { if (context.GetUndoManager().HasPendingInteractiveChange() && !ImGui::IsAnyItemActive()) { context.GetUndoManager().FinalizeInteractiveChange(); } } } // namespace Actions } // namespace Editor } // namespace XCEngine