From f7cfb93a81a6a0ee7cedb2debb0de1dfb9f7fd63 Mon Sep 17 00:00:00 2001 From: Jacob Domagala Date: Sun, 25 Feb 2024 23:08:29 +0100 Subject: [PATCH 1/6] [#194]: Don't make the recently selected GameObject a main selected one, when we're doing group select --- editor/editor.cpp | 4 ++-- editor/gui/editor_gui.cpp | 11 +++++++---- editor/gui/editor_gui.hpp | 2 +- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/editor/editor.cpp b/editor/editor.cpp index 8d20910b..598ce141 100644 --- a/editor/editor.cpp +++ b/editor/editor.cpp @@ -181,7 +181,7 @@ Editor::MouseButtonCallback(MouseButtonEvent& event) for (const auto object : selectedObjects) { - gui_.ObjectSelected(object); + gui_.ObjectSelected(object, true); const auto& objectPos = currentLevel_->GetGameObjectRef(object).GetCenteredPosition(); @@ -570,7 +570,7 @@ Editor::SelectGameObject(Object::ID newSelectedGameObject) } currentSelectedGameObject_ = newSelectedGameObject; - gui_.ObjectSelected(currentSelectedGameObject_); + gui_.ObjectSelected(currentSelectedGameObject_, false); // Make sure to render animation points if needed auto& gameObject = currentLevel_->GetGameObjectRef(newSelectedGameObject); diff --git a/editor/gui/editor_gui.cpp b/editor/gui/editor_gui.cpp index 46320236..41fe5606 100644 --- a/editor/gui/editor_gui.cpp +++ b/editor/gui/editor_gui.cpp @@ -4,6 +4,7 @@ #include "game_object.hpp" #include "helpers.hpp" #include "icons.hpp" +#include "input/input_manager.hpp" #include "renderer/renderer.hpp" #include "renderer/shader.hpp" #include "renderer/texture.hpp" @@ -11,7 +12,6 @@ #include "renderer/vulkan_common.hpp" #include "types.hpp" #include "utils/file_manager.hpp" -#include "input/input_manager.hpp" #include #include @@ -146,7 +146,7 @@ EditorGUI::UpdateUI() } ImGui::Render(); - + setScrollTo_ = {}; } @@ -183,12 +183,15 @@ EditorGUI::LevelLoaded(const std::shared_ptr< Level >& loadedLevel) } void -EditorGUI::ObjectSelected(Object::ID ID) +EditorGUI::ObjectSelected(Object::ID ID, bool groupSelect) { objectsInfo_[ID].second = true; setScrollTo_ = ID; - currentlySelectedGameObject_ = ID; + if (not groupSelect) + { + currentlySelectedGameObject_ = ID; + } } void diff --git a/editor/gui/editor_gui.hpp b/editor/gui/editor_gui.hpp index 09dd830c..2643503c 100644 --- a/editor/gui/editor_gui.hpp +++ b/editor/gui/editor_gui.hpp @@ -54,7 +54,7 @@ class EditorGUI : public InputListener LevelLoaded(const std::shared_ptr< Level >& loadedLevel); void - ObjectSelected(Object::ID ID); + ObjectSelected(Object::ID ID, bool groupSelect); void ObjectUnselected(Object::ID ID); From bd1a3c77797c2b0f621bb6ae13bb9e6609fa3e91 Mon Sep 17 00:00:00 2001 From: Jacob Domagala Date: Mon, 26 Feb 2024 22:48:21 +0100 Subject: [PATCH 2/6] [#194]: Allow for group edit of collision and render layer --- editor/gui/editor_gui.hpp | 3 ++ editor/gui/editor_gui_object.cpp | 74 +++++++++++++++++++++++++++----- engine/renderer/sprite.cpp | 4 ++ 3 files changed, 71 insertions(+), 10 deletions(-) diff --git a/editor/gui/editor_gui.hpp b/editor/gui/editor_gui.hpp index 2643503c..21d41154 100644 --- a/editor/gui/editor_gui.hpp +++ b/editor/gui/editor_gui.hpp @@ -90,6 +90,9 @@ class EditorGUI : public InputListener void RenderGameObjectContent(); + void + RenderGroupSelectModifications(); + void RenderCreateNewLevelWindow(); diff --git a/editor/gui/editor_gui_object.cpp b/editor/gui/editor_gui_object.cpp index 00c16ab6..bc15fd57 100644 --- a/editor/gui/editor_gui_object.cpp +++ b/editor/gui/editor_gui_object.cpp @@ -80,20 +80,79 @@ EditorGUI::RenderSelectedObjectsMenu() ImGui::EndChild(); - // If the user selects Objects from the List if (currentlySelectedGameObject_ != Object::INVALID_ID) { RenderGameObjectContent(); } + else + { + RenderGroupSelectModifications(); + } ImGui::End(); } +void +EditorGUI::RenderGroupSelectModifications() +{ + ImGui::SetNextItemOpen(true); + if (ImGui::CollapsingHeader("Group Action")) + { + if (ImGui::BeginTable("ObjectsTable", 2)) + { + // NOLINTNEXTLINE + static int groupLayer = 0; + CreateActionRowLabel("RenderLayer", [this] { + const auto items = std::to_array< std::string >( + {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"}); + if (ImGui::BeginCombo("##combo", fmt::format("{}", groupLayer).c_str())) + { + for (const auto& item : items) + { + if (ImGui::Selectable(item.c_str())) + { + parent_.AddToWorkQueue([item, this] { + const auto layer = std::stoi(item); + const auto& gameObjects = parent_.GetSelectedObjects(); + for (auto object : gameObjects) + { + parent_.GetLevel() + .GetGameObjectRef(object) + .GetSprite() + .ChangeRenderLayer(layer); + } + }); + } + } + ImGui::EndCombo(); + } + }); + // NOLINTNEXTLINE + static bool groupHasCollision = false; + CreateActionRowLabel("Has Collision", [this] { + if (ImGui::Checkbox("##GroupHasCollision", &groupHasCollision)) + { + parent_.AddToWorkQueue([this] { + const auto& gameObjects = parent_.GetSelectedObjects(); + for (auto object : gameObjects) + { + parent_.GetLevel().GetGameObjectRef(object).SetHasCollision(groupHasCollision); + } + parent_.GetLevel().UpdateCollisionTexture(); + }); + } + }); + + ImGui::EndTable(); + } + } +} + void EditorGUI::RenderGameObjectContent() { ImGui::SetNextItemOpen(true); - if (ImGui::CollapsingHeader("General")) + if (ImGui::CollapsingHeader("Selected")) { auto& gameObject = currentLevel_->GetGameObjectRef(currentlySelectedGameObject_); @@ -126,11 +185,7 @@ EditorGUI::RenderGameObjectContent() { parent_.AddToWorkQueue([&gameObject, item] { const auto layer = std::stoi(item); - const auto oldLayer = gameObject.GetSprite().GetRenderInfo().layer; gameObject.GetSprite().ChangeRenderLayer(layer); - - renderer::SetupVertexBuffer(oldLayer); - renderer::SetupVertexBuffer(layer); }); } } @@ -174,11 +229,10 @@ EditorGUI::RenderGameObjectContent() }); DrawWidget("Rotate", [&gameObject]() { - auto rotation = - gameObject.GetSprite().GetRotation(renderer::RotationType::degrees); + auto rotation = gameObject.GetSprite().GetRotation(renderer::RotationType::degrees); if (ImGui::InputFloat("##Rotate", &rotation, - glm::degrees(renderer::Sprite::ROTATION_RANGE.first), - glm::degrees(renderer::Sprite::ROTATION_RANGE.second))) + glm::degrees(renderer::Sprite::ROTATION_RANGE.first), + glm::degrees(renderer::Sprite::ROTATION_RANGE.second))) { gameObject.Rotate(glm::radians(rotation)); } diff --git a/engine/renderer/sprite.cpp b/engine/renderer/sprite.cpp index a339b3df..98367742 100644 --- a/engine/renderer/sprite.cpp +++ b/engine/renderer/sprite.cpp @@ -39,9 +39,13 @@ Sprite::ChangeRenderLayer(int32_t newLayer) } const auto transformMat = ComputeModelMat(); + const auto oldLayer = renderInfo_.layer; renderInfo_ = MeshLoaded(vertices_, textures_, transformMat, currentState_.color_); changed_ = true; + + SetupVertexBuffer(oldLayer); + SetupVertexBuffer(newLayer); } void From 218c49490f2a4b21460145352aa7e9ca10261a69 Mon Sep 17 00:00:00 2001 From: Jakub Domagala Date: Fri, 1 Mar 2024 16:21:51 +0100 Subject: [PATCH 3/6] [#194]: Fix background's layer --- engine/game/level.cpp | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/engine/game/level.cpp b/engine/game/level.cpp index deddc5fa..5c79c990 100644 --- a/engine/game/level.cpp +++ b/engine/game/level.cpp @@ -562,10 +562,9 @@ Level::LoadPremade(const std::string& fileName, const glm::ivec2& size) locked_ = false; levelSize_ = size; - background_.SetSpriteTextured(glm::vec3(static_cast< float >(levelSize_.x) / 2.0f, - static_cast< float >(levelSize_.y) / 2.0f, - renderer::LAYER_10), - size, fileName); + background_.SetSpriteTextured(glm::vec2(static_cast< float >(levelSize_.x) / 2.0f, + static_cast< float >(levelSize_.y) / 2.0f), + size, fileName, 10); baseTexture_ = background_.GetTexture()->GetID(); } From f3715ea200a50abc8cd1a0a14e020be23b0d694d Mon Sep 17 00:00:00 2001 From: Jakub Domagala Date: Fri, 1 Mar 2024 16:29:08 +0100 Subject: [PATCH 4/6] [#194]: Make group layer change persistent in UI and fix labels --- editor/gui/editor_gui_object.cpp | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/editor/gui/editor_gui_object.cpp b/editor/gui/editor_gui_object.cpp index bc15fd57..2b094e67 100644 --- a/editor/gui/editor_gui_object.cpp +++ b/editor/gui/editor_gui_object.cpp @@ -103,9 +103,9 @@ EditorGUI::RenderGroupSelectModifications() // NOLINTNEXTLINE static int groupLayer = 0; CreateActionRowLabel("RenderLayer", [this] { - const auto items = std::to_array< std::string >( - {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"}); - if (ImGui::BeginCombo("##combo", fmt::format("{}", groupLayer).c_str())) + const auto items = + std::to_array< std::string >({"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"}); + if (ImGui::BeginCombo("##GroupSetLayer", fmt::format("{}", groupLayer).c_str())) { for (const auto& item : items) { @@ -121,6 +121,8 @@ EditorGUI::RenderGroupSelectModifications() .GetSprite() .ChangeRenderLayer(layer); } + + groupLayer = layer; }); } } @@ -173,10 +175,10 @@ EditorGUI::RenderGameObjectContent() if (ImGui::BeginTable("ObjectTable", 2)) { CreateActionRowLabel("RenderLayer", [this, &gameObject] { - const auto items = std::to_array< std::string >( - {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "10"}); + const auto items = + std::to_array< std::string >({"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"}); if (ImGui::BeginCombo( - "##combo", + "##ObjectSetLayer", fmt::format("{}", gameObject.GetSprite().GetRenderInfo().layer).c_str())) { for (const auto& item : items) From 992b9592a8f8f9fd02cac3840d234359c6ea1d2e Mon Sep 17 00:00:00 2001 From: Jakub Domagala Date: Sat, 2 Mar 2024 01:34:18 +0100 Subject: [PATCH 5/6] [#194]: Add warning label for group select modifications when not all Objects have the same properties on collision and render layer --- editor/editor.cpp | 9 +-- editor/gui/editor_gui.cpp | 37 +++++++++++ editor/gui/editor_gui.hpp | 5 ++ editor/gui/editor_gui_object.cpp | 110 ++++++++++++++++++++----------- 4 files changed, 118 insertions(+), 43 deletions(-) diff --git a/editor/editor.cpp b/editor/editor.cpp index 598ce141..cc729d95 100644 --- a/editor/editor.cpp +++ b/editor/editor.cpp @@ -173,13 +173,14 @@ Editor::MouseButtonCallback(MouseButtonEvent& event) gui_.ObjectUnselected(object); } - - auto& firstObject = currentLevel_->GetGameObjectRef(selectedObjects.front()); + + selectedObjects_ = selectedObjects; + auto& firstObject = currentLevel_->GetGameObjectRef(selectedObjects_.front()); auto gizmoPos = firstObject.GetCenteredPosition(); glm::vec2 min = gizmoPos; glm::vec2 max = gizmoPos; - for (const auto object : selectedObjects) + for (const auto object : selectedObjects_) { gui_.ObjectSelected(object, true); const auto& objectPos = @@ -196,7 +197,7 @@ Editor::MouseButtonCallback(MouseButtonEvent& event) }; } - selectedObjects_ = selectedObjects; + gizmoActive_ = true; gizmo_.Show(); diff --git a/editor/gui/editor_gui.cpp b/editor/gui/editor_gui.cpp index 41fe5606..7796a35f 100644 --- a/editor/gui/editor_gui.cpp +++ b/editor/gui/editor_gui.cpp @@ -27,6 +27,39 @@ EditorGUI::EditorGUI(Editor& parent) : parent_(parent) { } +void +EditorGUI::RecalculateCommonRenderLayerAndColision() +{ + const auto& objects = parent_.GetSelectedObjects(); + + if (objects.empty()) + { + return; + } + + const auto& gameObject = parent_.GetLevel().GetGameObjectRef(objects.front()); + commonCollision_ = {true, gameObject.GetHasCollision()}; + commonRenderLayer_ = {true, gameObject.GetSprite().GetRenderInfo().layer}; + + if (objects.size() > 1) + { + for (int32_t idx = 1; idx < objects.size(); ++idx) + { + const auto& gameObject = parent_.GetLevel().GetGameObjectRef(objects.at(idx)); + if (commonCollision_.first and (gameObject.GetHasCollision() != commonCollision_.second)) + { + commonCollision_.first = false; + } + + if (commonRenderLayer_.first + and (gameObject.GetSprite().GetRenderInfo().layer != commonRenderLayer_.second)) + { + commonRenderLayer_.first = false; + } + } + } +} + void EditorGUI::KeyCallback(KeyEvent& event) { @@ -188,6 +221,8 @@ EditorGUI::ObjectSelected(Object::ID ID, bool groupSelect) objectsInfo_[ID].second = true; setScrollTo_ = ID; + RecalculateCommonRenderLayerAndColision(); + if (not groupSelect) { currentlySelectedGameObject_ = ID; @@ -200,6 +235,8 @@ EditorGUI::ObjectUnselected(Object::ID ID) objectsInfo_[currentlySelectedGameObject_].second = false; currentlySelectedGameObject_ = Object::INVALID_ID; + RecalculateCommonRenderLayerAndColision(); + objectsInfo_[ID].second = false; if (currentlySelectedGameObject_ == ID) { diff --git a/editor/gui/editor_gui.hpp b/editor/gui/editor_gui.hpp index 21d41154..404d626a 100644 --- a/editor/gui/editor_gui.hpp +++ b/editor/gui/editor_gui.hpp @@ -99,6 +99,9 @@ class EditorGUI : public InputListener void RenderExitWindow(); + void + RecalculateCommonRenderLayerAndColision(); + private: static void PrepareResources(); @@ -125,6 +128,8 @@ class EditorGUI : public InputListener // Data needed for loaded objects menu std::unordered_map< Object::ID, std::pair< std::string, bool > > objectsInfo_ = {}; Object::ID setScrollTo_ = Object::INVALID_ID; + std::pair< bool, int32_t > commonRenderLayer_ = {false, 0}; + std::pair< bool, bool > commonCollision_ = {false, false}; }; } // namespace looper diff --git a/editor/gui/editor_gui_object.cpp b/editor/gui/editor_gui_object.cpp index 2b094e67..374f2a2e 100644 --- a/editor/gui/editor_gui_object.cpp +++ b/editor/gui/editor_gui_object.cpp @@ -98,52 +98,84 @@ EditorGUI::RenderGroupSelectModifications() ImGui::SetNextItemOpen(true); if (ImGui::CollapsingHeader("Group Action")) { - if (ImGui::BeginTable("ObjectsTable", 2)) + if (ImGui::BeginTable("ObjectsTable", 3)) { - // NOLINTNEXTLINE - static int groupLayer = 0; - CreateActionRowLabel("RenderLayer", [this] { - const auto items = - std::to_array< std::string >({"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"}); - if (ImGui::BeginCombo("##GroupSetLayer", fmt::format("{}", groupLayer).c_str())) - { - for (const auto& item : items) + const auto totalWidth = ImGui::GetContentRegionAvail().x; + + ImGui::TableSetupColumn("Label", ImGuiTableColumnFlags_WidthStretch, 0.55f * totalWidth); + ImGui::TableSetupColumn("Value", ImGuiTableColumnFlags_WidthStretch, 0.35f * totalWidth); + ImGui::TableSetupColumn("Button", ImGuiTableColumnFlags_WidthStretch, 0.10f * totalWidth); + + CreateActionRowLabel( + "RenderLayer", + [this] { + const auto items = + std::to_array< std::string >({"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"}); + if (ImGui::BeginCombo("##GroupSetLayer", + fmt::format("{}", commonRenderLayer_.second).c_str())) { - if (ImGui::Selectable(item.c_str())) + for (const auto& item : items) { - parent_.AddToWorkQueue([item, this] { - const auto layer = std::stoi(item); - const auto& gameObjects = parent_.GetSelectedObjects(); - for (auto object : gameObjects) - { - parent_.GetLevel() - .GetGameObjectRef(object) - .GetSprite() - .ChangeRenderLayer(layer); - } - - groupLayer = layer; - }); + if (ImGui::Selectable(item.c_str())) + { + parent_.AddToWorkQueue([item, this] { + const auto layer = std::stoi(item); + const auto& gameObjects = parent_.GetSelectedObjects(); + for (auto object : gameObjects) + { + parent_.GetLevel() + .GetGameObjectRef(object) + .GetSprite() + .ChangeRenderLayer(layer); + } + + commonRenderLayer_.second = layer; + }); + } } + ImGui::EndCombo(); } - ImGui::EndCombo(); - } - }); - // NOLINTNEXTLINE - static bool groupHasCollision = false; - CreateActionRowLabel("Has Collision", [this] { - if (ImGui::Checkbox("##GroupHasCollision", &groupHasCollision)) - { - parent_.AddToWorkQueue([this] { - const auto& gameObjects = parent_.GetSelectedObjects(); - for (auto object : gameObjects) + }, + [this] { + if (not commonRenderLayer_.first) + { + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4{1.0f, 0.5f, 0.0f, 1.0f}); + ImGui::Button(ICON_FA_CIRCLE_EXCLAMATION "##LayerNotCommon"); + if (ImGui::IsItemHovered()) { - parent_.GetLevel().GetGameObjectRef(object).SetHasCollision(groupHasCollision); + ImGui::SetTooltip("Not all selcted Objects have the same layer set!"); } - parent_.GetLevel().UpdateCollisionTexture(); - }); - } - }); + ImGui::PopStyleColor(1); + } + }); + CreateActionRowLabel( + "Has Collision", + [this] { + if (ImGui::Checkbox("##GroupHasCollision", &commonCollision_.second)) + { + parent_.AddToWorkQueue([this] { + const auto& gameObjects = parent_.GetSelectedObjects(); + for (auto object : gameObjects) + { + parent_.GetLevel().GetGameObjectRef(object).SetHasCollision( + commonCollision_.second); + } + parent_.GetLevel().UpdateCollisionTexture(); + }); + } + }, + [this] { + if (not commonCollision_.first) + { + ImGui::PushStyleColor(ImGuiCol_Text, ImVec4{1.0f, 0.5f, 0.0f, 1.0f}); + ImGui::Button(ICON_FA_CIRCLE_EXCLAMATION "##CollisionNotCommon"); + if (ImGui::IsItemHovered()) + { + ImGui::SetTooltip("Not all selected Objects have the same collision set!"); + } + ImGui::PopStyleColor(1); + } + }); ImGui::EndTable(); } From 4db4bebbbe01767aae3adb722beca03c4cc5680d Mon Sep 17 00:00:00 2001 From: Jakub Domagala Date: Sat, 2 Mar 2024 13:43:01 +0100 Subject: [PATCH 6/6] [#194]: Working group modification with warnings --- .github/workflows/ubuntu.yml | 3 +- editor/editor.cpp | 4 +++ editor/gui/editor_gui.cpp | 50 ++++++++++++++++---------------- editor/gui/editor_gui.hpp | 4 +-- editor/gui/editor_gui_object.cpp | 44 ++++++++++++++++++++++++---- 5 files changed, 71 insertions(+), 34 deletions(-) diff --git a/.github/workflows/ubuntu.yml b/.github/workflows/ubuntu.yml index e70b6e00..ec1221df 100644 --- a/.github/workflows/ubuntu.yml +++ b/.github/workflows/ubuntu.yml @@ -26,7 +26,8 @@ jobs: sudo apt-get install -y xorg-dev llvm-dev iwyu clang++-15 libx11-xcb-dev libxcb-render-util0-dev \ libxcb-xkb-dev libxcb-icccm4-dev libxcb-image0-dev libxcb-keysyms1-dev libxcb-randr0-dev \ libxcb-shape0-dev libxcb-sync-dev libxcb-xfixes0-dev libxcb-xinerama0-dev libxcb-dri3-dev \ - libxcb-util-dev libxcb-cursor-dev + libxcb-util-dev libxcb-cursor-dev libx11-dev libfontenc-dev libice-dev libsm-dev libxau-dev libxaw7-dev \ + libxcb-glx0-dev libxcb-dri2-0-dev libxcb-present-dev libxcb-composite0-dev libxcb-ewmh-dev libxcb-res0-dev pip install conan diff --git a/editor/editor.cpp b/editor/editor.cpp index cc729d95..757c3672 100644 --- a/editor/editor.cpp +++ b/editor/editor.cpp @@ -496,6 +496,10 @@ Editor::HandleGameObjectClicked(Object::ID newSelectedGameObject, bool groupSele } selectedObjects_.push_back(newSelectedGameObject); + if (groupSelect) + { + gui_.ObjectSelected(newSelectedGameObject, groupSelect); + } } movementOnGameObject_ = !fromGUI; diff --git a/editor/gui/editor_gui.cpp b/editor/gui/editor_gui.cpp index 7796a35f..94e1212c 100644 --- a/editor/gui/editor_gui.cpp +++ b/editor/gui/editor_gui.cpp @@ -30,32 +30,25 @@ EditorGUI::EditorGUI(Editor& parent) : parent_(parent) void EditorGUI::RecalculateCommonRenderLayerAndColision() { - const auto& objects = parent_.GetSelectedObjects(); - - if (objects.empty()) + if (selectedObjects_.empty()) { return; } - const auto& gameObject = parent_.GetLevel().GetGameObjectRef(objects.front()); - commonCollision_ = {true, gameObject.GetHasCollision()}; - commonRenderLayer_ = {true, gameObject.GetSprite().GetRenderInfo().layer}; + const auto& [idFirst, collisionFirst, layerFirst] = selectedObjects_.front(); + commonRenderLayer_ = {true, layerFirst}; + commonCollision_ = {true, collisionFirst}; - if (objects.size() > 1) + for (uint32_t idx = 1; idx < selectedObjects_.size(); idx++) { - for (int32_t idx = 1; idx < objects.size(); ++idx) + const auto& [id, collision, layer] = selectedObjects_.at(idx); + if (commonRenderLayer_.first and (layer != commonRenderLayer_.second)) + { + commonRenderLayer_.first = false; + } + if (commonCollision_.first and (collision != commonCollision_.second)) { - const auto& gameObject = parent_.GetLevel().GetGameObjectRef(objects.at(idx)); - if (commonCollision_.first and (gameObject.GetHasCollision() != commonCollision_.second)) - { - commonCollision_.first = false; - } - - if (commonRenderLayer_.first - and (gameObject.GetSprite().GetRenderInfo().layer != commonRenderLayer_.second)) - { - commonRenderLayer_.first = false; - } + commonCollision_.first = false; } } } @@ -221,6 +214,9 @@ EditorGUI::ObjectSelected(Object::ID ID, bool groupSelect) objectsInfo_[ID].second = true; setScrollTo_ = ID; + const auto& gameObject = parent_.GetLevel().GetGameObjectRef(ID); + selectedObjects_.emplace_back( + ID, gameObject.GetHasCollision(), gameObject.GetSprite().GetRenderInfo().layer); RecalculateCommonRenderLayerAndColision(); if (not groupSelect) @@ -232,16 +228,20 @@ EditorGUI::ObjectSelected(Object::ID ID, bool groupSelect) void EditorGUI::ObjectUnselected(Object::ID ID) { - objectsInfo_[currentlySelectedGameObject_].second = false; - currentlySelectedGameObject_ = Object::INVALID_ID; - - RecalculateCommonRenderLayerAndColision(); - - objectsInfo_[ID].second = false; if (currentlySelectedGameObject_ == ID) { currentlySelectedGameObject_ = Object::INVALID_ID; } + else + { + objectsInfo_[ID].second = false; + + selectedObjects_.erase(stl::find_if(selectedObjects_, [ID](const auto& obj) { + const auto [id, collision, layer] = obj; + return id == ID; + })); + RecalculateCommonRenderLayerAndColision(); + } } void diff --git a/editor/gui/editor_gui.hpp b/editor/gui/editor_gui.hpp index 404d626a..672ff312 100644 --- a/editor/gui/editor_gui.hpp +++ b/editor/gui/editor_gui.hpp @@ -99,8 +99,7 @@ class EditorGUI : public InputListener void RenderExitWindow(); - void - RecalculateCommonRenderLayerAndColision(); + void RecalculateCommonRenderLayerAndColision(); private: static void @@ -130,6 +129,7 @@ class EditorGUI : public InputListener Object::ID setScrollTo_ = Object::INVALID_ID; std::pair< bool, int32_t > commonRenderLayer_ = {false, 0}; std::pair< bool, bool > commonCollision_ = {false, false}; + std::vector > selectedObjects_ = {}; }; } // namespace looper diff --git a/editor/gui/editor_gui_object.cpp b/editor/gui/editor_gui_object.cpp index 374f2a2e..2871877e 100644 --- a/editor/gui/editor_gui_object.cpp +++ b/editor/gui/editor_gui_object.cpp @@ -111,6 +111,7 @@ EditorGUI::RenderGroupSelectModifications() [this] { const auto items = std::to_array< std::string >({"1", "2", "3", "4", "5", "6", "7", "8", "9", "10"}); + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); if (ImGui::BeginCombo("##GroupSetLayer", fmt::format("{}", commonRenderLayer_.second).c_str())) { @@ -119,17 +120,22 @@ EditorGUI::RenderGroupSelectModifications() if (ImGui::Selectable(item.c_str())) { parent_.AddToWorkQueue([item, this] { - const auto layer = std::stoi(item); + const auto newLayer = std::stoi(item); const auto& gameObjects = parent_.GetSelectedObjects(); for (auto object : gameObjects) { parent_.GetLevel() .GetGameObjectRef(object) .GetSprite() - .ChangeRenderLayer(layer); + .ChangeRenderLayer(newLayer); } - commonRenderLayer_.second = layer; + for (auto& [id, collision, layer] : selectedObjects_) + { + layer = newLayer; + } + + commonRenderLayer_ = {true, newLayer}; }); } } @@ -151,6 +157,7 @@ EditorGUI::RenderGroupSelectModifications() CreateActionRowLabel( "Has Collision", [this] { + ImGui::SetNextItemWidth(ImGui::GetContentRegionAvail().x); if (ImGui::Checkbox("##GroupHasCollision", &commonCollision_.second)) { parent_.AddToWorkQueue([this] { @@ -160,6 +167,13 @@ EditorGUI::RenderGroupSelectModifications() parent_.GetLevel().GetGameObjectRef(object).SetHasCollision( commonCollision_.second); } + + for (auto& [id, collision, layer] : selectedObjects_) + { + collision = commonCollision_.second; + } + commonCollision_.first = true; + parent_.GetLevel().UpdateCollisionTexture(); }); } @@ -217,9 +231,19 @@ EditorGUI::RenderGameObjectContent() { if (ImGui::Selectable(item.c_str())) { - parent_.AddToWorkQueue([&gameObject, item] { - const auto layer = std::stoi(item); - gameObject.GetSprite().ChangeRenderLayer(layer); + parent_.AddToWorkQueue([&gameObject, item, this] { + const auto newLayer = std::stoi(item); + gameObject.GetSprite().ChangeRenderLayer(newLayer); + + auto obj = + stl::find_if(selectedObjects_, + [curID = currentlySelectedGameObject_](const auto& obj) { + auto [id, collision, layer] = obj; + return id == curID; + }); + auto& [objID, objCollision, objLayer] = *obj; + objLayer = newLayer; + RecalculateCommonRenderLayerAndColision(); }); } } @@ -233,6 +257,14 @@ EditorGUI::RenderGameObjectContent() if (ImGui::Checkbox("##Has Collision", &collision)) { gameObject.SetHasCollision(collision); + auto obj = stl::find_if(selectedObjects_, + [curID = currentlySelectedGameObject_](const auto& obj) { + auto [id, hasCollision, layer] = obj; + return id == curID; + }); + auto& [objID, objCollision, objLayer] = *obj; + objCollision = collision; + RecalculateCommonRenderLayerAndColision(); parent_.GetLevel().UpdateCollisionTexture(); } });