diff --git a/src/features/editScene/systems/EditorUISystem.cpp b/src/features/editScene/systems/EditorUISystem.cpp index f2711ce..3ffceff 100644 --- a/src/features/editScene/systems/EditorUISystem.cpp +++ b/src/features/editScene/systems/EditorUISystem.cpp @@ -299,6 +299,15 @@ void EditorUISystem::renderHierarchyWindow() ImGui::EndMenu(); } + // Prefabs menu + if (ImGui::BeginMenu("Prefabs")) { + if (ImGui::MenuItem("Show Prefab Browser")) { + m_showPrefabBrowser = true; + m_refreshPrefabList = true; + } + ImGui::EndMenu(); + } + // Entity menu if (ImGui::BeginMenu("Entity")) { if (ImGui::MenuItem("New Entity", "Ctrl+N")) { @@ -1580,7 +1589,24 @@ void EditorUISystem::renderPrefabBrowser() for (const auto &file : m_prefabFiles) { std::string path = PrefabSystem::getPrefabsDirectory() + "/" + file; - if (ImGui::Selectable(file.c_str())) { + ImGui::Text("%s", file.c_str()); + ImGui::SameLine(); + + std::string editId = "Edit##" + file; + if (ImGui::Button(editId.c_str())) { + SceneSerializer serializer(m_world, + m_sceneMgr); + flecs::entity prefabRoot = + serializer.loadPrefabForEdit( + path, this); + if (prefabRoot.is_alive()) { + setSelectedEntity(prefabRoot); + } + } + ImGui::SameLine(); + + std::string instId = "Inst##" + file; + if (ImGui::Button(instId.c_str())) { Ogre::Vector3 pos(0, 0, 0); if (m_selectedEntity.is_alive() && m_selectedEntity.has()) { @@ -1597,7 +1623,8 @@ void EditorUISystem::renderPrefabBrowser() : flecs::entity::null(); auto instance = prefabSys.createInstance( path, parent, pos, - file.substr(0, file.find_last_of('.')), + file.substr(0, file.find_last_of('.')) + .c_str(), this); if (instance.is_alive()) { setSelectedEntity(instance); diff --git a/src/features/editScene/systems/EditorUISystem.hpp b/src/features/editScene/systems/EditorUISystem.hpp index d10bfc4..76cae55 100644 --- a/src/features/editScene/systems/EditorUISystem.hpp +++ b/src/features/editScene/systems/EditorUISystem.hpp @@ -252,7 +252,7 @@ private: bool m_showCreatePrefabDialog = false; flecs::entity m_prefabSourceEntity = flecs::entity::null(); char m_prefabNameBuffer[256] = { 0 }; - bool m_showPrefabBrowser = true; + bool m_showPrefabBrowser = false; std::vector m_prefabFiles; bool m_refreshPrefabList = true; diff --git a/src/features/editScene/systems/SceneSerializer.cpp b/src/features/editScene/systems/SceneSerializer.cpp index b213c44..6693bb9 100644 --- a/src/features/editScene/systems/SceneSerializer.cpp +++ b/src/features/editScene/systems/SceneSerializer.cpp @@ -852,6 +852,43 @@ bool SceneSerializer::savePrefab(flecs::entity rootEntity, } } +flecs::entity SceneSerializer::loadPrefabForEdit( + const std::string &filepath, EditorUISystem *uiSystem) +{ + try { + std::ifstream file(filepath); + if (!file.is_open()) { + m_lastError = "Failed to open prefab: " + filepath; + return flecs::entity::null(); + } + + nlohmann::json prefabJson; + file >> prefabJson; + file.close(); + + flecs::entity entity = m_world.entity(); + entity.add(); + if (prefabJson.contains("id")) { + m_entityMap[prefabJson["id"]] = entity; + } + + if (!prefabJson.contains("name")) { + entity.set( + EntityNameComponent("Prefab")); + } + + deserializeEntityComponents(entity, prefabJson, + flecs::entity::null(), + uiSystem, true, true, + true); + + return entity; + } catch (const std::exception &e) { + m_lastError = std::string("Prefab load error: ") + e.what(); + return flecs::entity::null(); + } +} + bool SceneSerializer::instantiatePrefab(flecs::entity instanceEntity, const std::string &filepath, EditorUISystem *uiSystem) diff --git a/src/features/editScene/systems/SceneSerializer.hpp b/src/features/editScene/systems/SceneSerializer.hpp index 80932ea..8eb127d 100644 --- a/src/features/editScene/systems/SceneSerializer.hpp +++ b/src/features/editScene/systems/SceneSerializer.hpp @@ -60,6 +60,20 @@ public: const std::string &filepath, EditorUISystem *uiSystem = nullptr); + /** + * Load a prefab file into the scene as editable entities. + * + * Unlike instantiatePrefab(), this creates a brand-new root + * entity WITH EditorMarkerComponent so it can be edited and + * saved back with savePrefab(). + * + * @param filepath Path to prefab JSON file. + * @param uiSystem Optional UI system for registering new entities. + * @return The created root entity, or null on failure. + */ + flecs::entity loadPrefabForEdit(const std::string &filepath, + EditorUISystem *uiSystem = nullptr); + private: // Serialization helpers nlohmann::json serializeEntity(flecs::entity entity);