diff --git a/CHANGELOG.md b/CHANGELOG.md index de27345376..c7676ef2a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - New feature guide focused on queries (#995, **@RiscadoA**). - ECS Statistics tesseratos plugin (#1024, **@RiscadoA**). - Global position, rotation and scale getters (#1002, **@DiogoMendonc-a**). +- Show childOf hierarchy on the world inspector (#991, **@diogomsmiranda**). ### Fixed diff --git a/tools/tesseratos/samples/main/assets/scenes/main.cubos b/tools/tesseratos/samples/main/assets/scenes/main.cubos index ba5a2a7e7a..e425ee14aa 100644 --- a/tools/tesseratos/samples/main/assets/scenes/main.cubos +++ b/tools/tesseratos/samples/main/assets/scenes/main.cubos @@ -17,7 +17,7 @@ "z": 2 } }, - "child1": { + "child": { "cubos::engine::Position": { "x": 3, "y": 3, @@ -25,7 +25,7 @@ }, "cubos::engine::ChildOf@parent": {} }, - "chil2": { + "child1": { "cubos::engine::Position": { "x": 4, "y": 4, @@ -33,7 +33,7 @@ }, "cubos::engine::ChildOf@parent": {} }, - "chil3": { + "child2": { "cubos::engine::Position": { "x": 5, "y": 5, @@ -41,36 +41,44 @@ }, "cubos::engine::ChildOf@parent": {} }, - "parent2": { + "parent1": { "cubos::engine::Position": { "x": 6, "y": 6, "z": 6 } }, - "child4": { + "child3": { "cubos::engine::Position": { "x": 7, "y": 7, "z": 7 }, - "cubos::engine::ChildOf@parent2": {} + "cubos::engine::ChildOf@parent1": {} }, - "chil5": { + "parent2": { "cubos::engine::Position": { "x": 8, "y": 8, "z": 8 }, - "cubos::engine::ChildOf@parent2": {} + "cubos::engine::ChildOf@parent1": {} }, - "chil6": { + "child4": { "cubos::engine::Position": { "x": 9, "y": 9, "z": 9 }, + "cubos::engine::ChildOf@parent1": {} + }, + "child5": { + "cubos::engine::Position": { + "x": 10, + "y": 10, + "z": 10 + }, "cubos::engine::ChildOf@parent2": {} - } + } } } \ No newline at end of file diff --git a/tools/tesseratos/src/tesseratos/world_inspector/plugin.cpp b/tools/tesseratos/src/tesseratos/world_inspector/plugin.cpp index c8c76e9070..84ba934b04 100644 --- a/tools/tesseratos/src/tesseratos/world_inspector/plugin.cpp +++ b/tools/tesseratos/src/tesseratos/world_inspector/plugin.cpp @@ -4,6 +4,7 @@ #include #include +#include #include #include @@ -14,9 +15,56 @@ using cubos::core::ecs::Name; using cubos::core::ecs::Opt; using cubos::core::ecs::Query; using cubos::core::ecs::World; +using cubos::core::ecs::WriteResource; +using cubos::engine::ChildOf; using cubos::engine::Cubos; +static void show(Entity entity, Query, const ChildOf&, Entity> childOf, Opt name, + tesseratos::EntitySelector& selector) +{ + auto displayName = name.contains() ? name->value : std::to_string(entity.index); + auto children = childOf.pin(1, entity); + auto textColor = (ImVec4)ImColor(255, 255, 255); + + selector.selection == entity ? textColor = (ImVec4)ImColor(149, 252, 75) + : textColor = (ImVec4)ImColor(255, 255, 255); + + // check if entity has children + if (children.empty()) + { + ImGui::PushStyleColor(ImGuiCol_Text, textColor); + ImGui::Selectable((" " + displayName).c_str(), selector.selection == entity); + ImGui::PopStyleColor(); + + if (ImGui::IsItemClicked(0)) + { + selector.selection = entity; + } + + return; + } + + ImGui::PushStyleColor(ImGuiCol_Text, textColor); + if (ImGui::TreeNode(displayName.c_str())) + { + ImGui::PopStyleColor(); + + if (ImGui::IsItemClicked(0)) + { + selector.selection = entity; + } + for (auto [child, nameChild, _, parent] : children) + { + show(child, childOf, nameChild, selector); + } + ImGui::TreePop(); + + return; + } + ImGui::PopStyleColor(); +} + void tesseratos::worldInspectorPlugin(Cubos& cubos) { cubos.addPlugin(cubos::engine::imguiPlugin); @@ -24,7 +72,8 @@ void tesseratos::worldInspectorPlugin(Cubos& cubos) cubos.addPlugin(entitySelectorPlugin); cubos.system("show World Inspector UI") .tagged("cubos.imgui") - .call([](World& world, Query> query) { + .call([](World& world, Query> all, + Query, const ChildOf&, Entity> query) { if (!(world.write().get().isOpen("World Inspector"))) { return; @@ -35,28 +84,14 @@ void tesseratos::worldInspectorPlugin(Cubos& cubos) ImGui::Begin("World Inspector"); if (!ImGui::IsWindowCollapsed()) { - int n = 0; - for (auto [entity, name] : query) + for (auto [entity, name] : all) { - ImGui::PushID(n); - - if (name.contains()) - { - ImGui::BulletText("%s", name->value.c_str()); - } - else - { - ImGui::BulletText("%s", std::to_string(entity.index).c_str()); - } - - ImGui::SameLine(); - if (ImGui::Button("Select")) + if (!query.pin(0, entity).empty()) { - selector.get().selection = entity; + continue; // Skip all entities with parents } - n++; - ImGui::PopID(); + show(entity, query, name, selector.get()); } } ImGui::End();