#include "InspectorPanel.h" #include "Managers/SceneManager.h" #include "Managers/SelectionManager.h" #include "UI/UI.h" #include #include namespace XCEngine { namespace Editor { InspectorPanel::InspectorPanel() : Panel("Inspector") { 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() { 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(); } void InspectorPanel::RenderGameObject(::XCEngine::Components::GameObject* gameObject) { 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")) { ImGui::OpenPopup("AddComponent"); } RenderAddComponentPopup(gameObject); auto components = gameObject->GetComponents<::XCEngine::Components::Component>(); for (auto* component : components) { RenderComponent(component, gameObject); } } void InspectorPanel::RenderAddComponentPopup(::XCEngine::Components::GameObject* gameObject) { if (!ImGui::BeginPopup("AddComponent")) { return; } ImGui::PushStyleVar(ImGuiStyleVar_WindowPadding, ImVec2(12.0f, 10.0f)); ImGui::SeparatorText("Components"); if (ImGui::MenuItem("Transform", nullptr, false, !gameObject->GetComponent<::XCEngine::Components::TransformComponent>())) { gameObject->AddComponent<::XCEngine::Components::TransformComponent>(); ImGui::CloseCurrentPopup(); } ImGui::SeparatorText("Other"); ImGui::TextDisabled("No more components available"); ImGui::PopStyleVar(); ImGui::EndPopup(); } 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; } } } } }