Files
XCEngine/editor/src/panels/InspectorPanel.cpp

176 lines
6.5 KiB
C++
Raw Normal View History

#include "InspectorPanel.h"
#include "Managers/SceneManager.h"
#include "Managers/SelectionManager.h"
#include "UI/UI.h"
#include <XCEngine/Debug/Logger.h>
#include <imgui.h>
#include <string>
namespace XCEngine {
namespace Editor {
InspectorPanel::InspectorPanel() : Panel("Inspector") {
Debug::Logger::Get().Debug(Debug::LogCategory::General, "InspectorPanel constructed");
m_selectionHandlerId = SelectionManager::Get().OnSelectionChanged.Subscribe([this](uint64_t) {
m_selectedGameObject = SelectionManager::Get().GetSelectedEntity();
});
}
InspectorPanel::~InspectorPanel() {
SelectionManager::Get().OnSelectionChanged.Unsubscribe(m_selectionHandlerId);
}
void InspectorPanel::Render() {
Debug::Logger::Get().Debug(Debug::LogCategory::General, "InspectorPanel::Render START");
ImGui::Begin(m_name.c_str(), nullptr, ImGuiWindowFlags_None);
m_selectedGameObject = SelectionManager::Get().GetSelectedEntity();
if (m_selectedGameObject) {
RenderGameObject(m_selectedGameObject);
} else {
ImGui::Text("No object selected");
ImGui::TextColored(ImVec4(0.5f, 0.5f, 0.5f, 1.0f), "Select an object in Hierarchy");
}
ImGui::End();
Debug::Logger::Get().Debug(Debug::LogCategory::General, "InspectorPanel::Render END");
}
void InspectorPanel::RenderGameObject(::XCEngine::Components::GameObject* gameObject) {
Debug::Logger::Get().Debug(Debug::LogCategory::General, "RenderGameObject START");
char nameBuffer[256];
strcpy_s(nameBuffer, gameObject->GetName().c_str());
ImGui::InputText("##Name", nameBuffer, sizeof(nameBuffer));
if (ImGui::IsItemDeactivatedAfterEdit()) {
gameObject->SetName(nameBuffer);
}
ImGui::SameLine();
if (ImGui::Button("Add Component")) {
Debug::Logger::Get().Debug(Debug::LogCategory::General, "Add Component BUTTON CLICKED");
ImGui::OpenPopup("AddComponent");
}
RenderAddComponentPopup(gameObject);
auto components = gameObject->GetComponents<::XCEngine::Components::Component>();
for (auto* component : components) {
RenderComponent(component, gameObject);
}
Debug::Logger::Get().Debug(Debug::LogCategory::General, "RenderGameObject END");
}
void InspectorPanel::RenderAddComponentPopup(::XCEngine::Components::GameObject* gameObject) {
Debug::Logger::Get().Debug(Debug::LogCategory::General, "RenderAddComponentPopup called");
if (!gameObject) {
Debug::Logger::Get().Error(Debug::LogCategory::General, "ERROR: gameObject is nullptr!");
return;
}
if (!ImGui::BeginPopup("AddComponent")) {
Debug::Logger::Get().Debug(Debug::LogCategory::General, "BeginPopup returned false");
return;
}
Debug::Logger::Get().Debug(Debug::LogCategory::General, "BeginPopup succeeded");
ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(12.0f, 10.0f));
ImGui::SeparatorText("Components");
bool hasTransform = gameObject->GetComponent<::XCEngine::Components::TransformComponent>() != nullptr;
Debug::Logger::Get().Debug(Debug::LogCategory::General, hasTransform ? "Has Transform: yes" : "Has Transform: no");
Debug::Logger::Get().Debug(Debug::LogCategory::General, "About to check MenuItem condition");
if (ImGui::MenuItem("Transform", nullptr, false, !hasTransform)) {
Debug::Logger::Get().Debug(Debug::LogCategory::General, "MenuItem CLICKED! Before AddComponent");
auto* newComp = gameObject->AddComponent<::XCEngine::Components::TransformComponent>();
Debug::Logger::Get().Debug(Debug::LogCategory::General, newComp ? "AddComponent SUCCEEDED" : "AddComponent FAILED");
ImGui::CloseCurrentPopup();
} else {
Debug::Logger::Get().Debug(Debug::LogCategory::General, "MenuItem not clicked (disabled or condition false)");
}
ImGui::SeparatorText("Other");
ImGui::TextDisabled("No more components available");
Debug::Logger::Get().Debug(Debug::LogCategory::General, "About to EndPopup");
ImGui::EndPopup();
ImGui::PopStyleVar();
Debug::Logger::Get().Debug(Debug::LogCategory::General, "Popup closed");
}
void InspectorPanel::RenderComponent(::XCEngine::Components::Component* component, ::XCEngine::Components::GameObject* gameObject) {
if (!component) return;
const char* name = component->GetName().c_str();
ImGui::PushStyleVar(ImGuiStyleVar_FramePadding, ImVec2{4, 2});
ImGuiTreeNodeFlags flags =
ImGuiTreeNodeFlags_DefaultOpen |
ImGuiTreeNodeFlags_Framed |
ImGuiTreeNodeFlags_SpanAvailWidth |
ImGuiTreeNodeFlags_FramePadding |
ImGuiTreeNodeFlags_AllowOverlap;
bool open = ImGui::TreeNodeEx((void*)typeid(*component).hash_code(), flags, "%s", name);
ImGui::PopStyleVar();
bool removeComponent = false;
if (ImGui::BeginPopupContextItem("ComponentSettings")) {
if (ImGui::MenuItem("Remove Component")) {
removeComponent = true;
}
ImGui::EndPopup();
}
if (removeComponent) {
RemoveComponentByType(component, gameObject);
return;
}
if (open) {
if (auto* transform = dynamic_cast<::XCEngine::Components::TransformComponent*>(component)) {
::XCEngine::Math::Vector3 position = transform->GetLocalPosition();
::XCEngine::Math::Vector3 rotation = transform->GetLocalEulerAngles();
::XCEngine::Math::Vector3 scale = transform->GetLocalScale();
if (UI::DrawVec3("Position", position, 0.0f, 80.0f, 0.1f)) {
transform->SetLocalPosition(position);
}
if (UI::DrawVec3("Rotation", rotation, 0.0f, 80.0f, 1.0f)) {
transform->SetLocalEulerAngles(rotation);
}
if (UI::DrawVec3("Scale", scale, 1.0f, 80.0f, 0.1f)) {
transform->SetLocalScale(scale);
}
}
ImGui::TreePop();
}
}
void InspectorPanel::RemoveComponentByType(::XCEngine::Components::Component* component, ::XCEngine::Components::GameObject* gameObject) {
if (!component || !gameObject) return;
if (dynamic_cast<::XCEngine::Components::TransformComponent*>(component)) {
return;
}
auto components = gameObject->GetComponents<::XCEngine::Components::Component>();
for (auto* comp : components) {
if (comp == component) {
gameObject->RemoveComponent<::XCEngine::Components::Component>();
break;
}
}
}
}
}