feat: add "Add component" button

This commit is contained in:
2026-08-12 01:18:47 +02:00
parent 8c7302de49
commit c3c1d5ae28
5 changed files with 146 additions and 59 deletions
+68 -3
View File
@@ -2,6 +2,7 @@
#include <algorithm>
#include <cfloat>
#include <exception>
#include <string>
#include <unordered_set>
#include <vector>
@@ -14,6 +15,8 @@
#include <destrum/ObjectModel/Component.h>
#include <destrum/ObjectModel/GameObject.h>
#include <destrum/ObjectModel/Transform.h>
#include <destrum/Serialization/ComponentFactory.h>
#include <destrum/Serialization/ComponentRegistry.h>
namespace {
[[nodiscard]] bool IsInspectableObject(const GameObject* object) {
@@ -121,6 +124,8 @@ namespace ImGuiUtils {
const std::vector<std::shared_ptr<GameObject>>& objectsSource,
const std::vector<std::shared_ptr<GameObject>>& pendingAdditions,
ObjectId& selectedObjectId) {
RegisterEngineComponents();
std::vector<GameObject*> objects;
objects.reserve(objectsSource.size() + pendingAdditions.size());
@@ -268,9 +273,69 @@ namespace ImGuiUtils {
worldPosition.z);
}
if (ImGui::CollapsingHeader(
"Components",
ImGuiTreeNodeFlags_DefaultOpen)) {
const bool componentsOpen = ImGui::CollapsingHeader(
"Components",
ImGuiTreeNodeFlags_DefaultOpen);
if (componentsOpen) {
if (ImGui::Button("+ Add Component")) {
ImGui::OpenPopup("AddComponentPopup");
}
std::string addComponentError;
if (ImGui::BeginPopup("AddComponentPopup")) {
std::vector<std::string> componentTypes =
ComponentFactory::GetRegisteredTypeNames();
std::sort(componentTypes.begin(), componentTypes.end());
bool hasAvailableComponent = false;
for (const std::string& componentType : componentTypes) {
const bool alreadyAdded = std::any_of(
selectedObject->GetComponents().begin(),
selectedObject->GetComponents().end(),
[&componentType](const auto& component) {
return component != nullptr &&
!component->IsBeingDestroyed() &&
component->GetTypeName() == componentType;
});
if (alreadyAdded) {
const std::string label =
componentType + " (already added)";
ImGui::BeginDisabled();
ImGui::MenuItem(label.c_str());
ImGui::EndDisabled();
continue;
}
hasAvailableComponent = true;
if (ImGui::MenuItem(componentType.c_str())) {
try {
if (ComponentFactory::Create(
componentType,
*selectedObject) == nullptr) {
addComponentError =
"Component type is not registered: " +
componentType;
} else {
ImGui::CloseCurrentPopup();
}
} catch (const std::exception& exception) {
addComponentError = exception.what();
}
}
}
if (!hasAvailableComponent) {
ImGui::TextDisabled("All components are already added.");
}
if (!addComponentError.empty()) {
ImGui::TextWrapped("Failed to add component: %s",
addComponentError.c_str());
}
ImGui::EndPopup();
}
bool hasComponents = false;
for (const auto& component : selectedObject->GetComponents()) {
if (component == nullptr || component->IsBeingDestroyed()) {