2026-03-27 00:08:46 +08:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
|
|
#include "EditorActions.h"
|
|
|
|
|
#include "Commands/ComponentCommands.h"
|
|
|
|
|
#include "ComponentEditors/ComponentEditorRegistry.h"
|
2026-03-27 12:06:24 +08:00
|
|
|
#include "Core/EditorEvents.h"
|
2026-03-27 00:08:46 +08:00
|
|
|
#include "Core/IEditorContext.h"
|
2026-03-27 12:06:24 +08:00
|
|
|
#include "UI/PopupState.h"
|
2026-03-27 00:08:46 +08:00
|
|
|
#include "UI/UI.h"
|
|
|
|
|
|
|
|
|
|
#include <string>
|
|
|
|
|
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-27 12:06:24 +08:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-27 00:08:46 +08:00
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-27 12:06:24 +08:00
|
|
|
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();
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-27 00:08:46 +08:00
|
|
|
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);
|
|
|
|
|
});
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-27 12:06:24 +08:00
|
|
|
inline void FinalizeInspectorInteractiveChangeIfIdle(IEditorContext& context) {
|
|
|
|
|
if (context.GetUndoManager().HasPendingInteractiveChange() && !ImGui::IsAnyItemActive()) {
|
|
|
|
|
context.GetUndoManager().FinalizeInteractiveChange();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2026-03-27 00:08:46 +08:00
|
|
|
} // namespace Actions
|
|
|
|
|
} // namespace Editor
|
|
|
|
|
} // namespace XCEngine
|