diff --git a/SHADE_Engine/src/Common/SHAllComponents.h b/SHADE_Engine/src/Common/SHAllComponents.h new file mode 100644 index 00000000..9d280677 --- /dev/null +++ b/SHADE_Engine/src/Common/SHAllComponents.h @@ -0,0 +1,15 @@ +#pragma once +#include "Camera/SHCameraComponent.h" +#include "Camera/SHCameraArmComponent.h" +#include "Math/Transform/SHTransformComponent.h" +#include "Graphics/MiddleEnd/Interface/SHRenderable.h" +#include "Physics/Interface/SHRigidBodyComponent.h" +#include "UI/SHCanvasComponent.h" +#include "UI/SHButtonComponent.h" +#include "UI/SHUIComponent.h" +#include "UI/SHToggleButtonComponent.h" +#include "UI/SHSliderComponent.h" +#include "Graphics/MiddleEnd/Lights/SHLightComponent.h" +#include "Graphics/MiddleEnd/Interface/SHRenderable.h" +#include "Physics/Interface/SHColliderComponent.h" +#include "Graphics/MiddleEnd/TextRendering/SHTextRenderableComponent.h" \ No newline at end of file diff --git a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp index a1bb29ca..a7ba7dc0 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/AssetBrowser/SHAssetBrowser.cpp @@ -239,10 +239,7 @@ namespace SHADE case AssetType::TEXTURE: break; case AssetType::MESH: break; case AssetType::SCENE: - if(auto editor = SHSystemManager::GetSystem()) - { editor->LoadScene(asset->id); - } break; case AssetType::PREFAB: break; case AssetType::MATERIAL: diff --git a/SHADE_Engine/src/Editor/EditorWindow/EditorPopups/SHEditorPopups.cpp b/SHADE_Engine/src/Editor/EditorWindow/EditorPopups/SHEditorPopups.cpp new file mode 100644 index 00000000..31e6edde --- /dev/null +++ b/SHADE_Engine/src/Editor/EditorWindow/EditorPopups/SHEditorPopups.cpp @@ -0,0 +1,33 @@ +#include "SHpch.h" +#include "SHEditorPopups.h" +#include "Editor/SHEditor.h" +#include "misc/cpp/imgui_stdlib.h" + +namespace SHADE +{ + void SHSceneSavePrompt::Draw() + { + if(Begin()) + { + static std::string newSceneName{}; + ImGui::Text("Enter new scene name"); + ImGui::InputText("##name", &newSceneName); + ImGui::BeginDisabled(newSceneName.empty()); + if (ImGui::Button("Save")) + { + editor->SaveScene(newSceneName); + newSceneName.clear(); + isOpen = false; + ImGui::CloseCurrentPopup(); + } + ImGui::EndDisabled(); + ImGui::SameLine(); + if (ImGui::Button("Cancel")) + { + isOpen = false; + ImGui::CloseCurrentPopup(); + } + ImGui::EndPopup(); + } + } +} \ No newline at end of file diff --git a/SHADE_Engine/src/Editor/EditorWindow/EditorPopups/SHEditorPopups.h b/SHADE_Engine/src/Editor/EditorWindow/EditorPopups/SHEditorPopups.h new file mode 100644 index 00000000..9e37a98a --- /dev/null +++ b/SHADE_Engine/src/Editor/EditorWindow/EditorPopups/SHEditorPopups.h @@ -0,0 +1,17 @@ +#pragma once + +#include "SH_API.h" +#include "Editor/EditorWindow/SHPopUpWindow.h" + +namespace SHADE +{ + class SHSceneSavePrompt : public SHPopUpWindow + { + public: + SHSceneSavePrompt():SHPopUpWindow("Save Scene As", true, 0, 0){} + void Draw() override; + + private: + + }; +} \ No newline at end of file diff --git a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp index 6ac5933c..ef4ad35e 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.cpp @@ -3,6 +3,11 @@ //#==============================================================# #include "SHpch.h" +//#==============================================================# +//|| Library Includes || +//#==============================================================# +#include + //#==============================================================# //|| SHADE Includes || //#==============================================================# @@ -16,14 +21,11 @@ #include "Tools/SHException.h" #include "Editor/IconsMaterialDesign.h" #include "SHHierarchyPanelCommands.h" - -//#==============================================================# -//|| Library Includes || -//#==============================================================# -#include +#include "Common/SHAllComponents.h" #include "Serialization/SHSerialization.h" #include "Tools/Utilities/SHClipboardUtilities.h" +#include "Tools/Utilities/SHStringUtilities.h" namespace SHADE @@ -80,7 +82,6 @@ namespace SHADE if (ImGui::IsWindowHovered() && !SHDragDrop::hasDragDrop && !ImGui::IsAnyItemHovered() && ImGui::IsMouseReleased(ImGuiMouseButton_Left)) { - if (auto editor = SHSystemManager::GetSystem()) editor->selectedEntities.clear(); } ImGui::SeparatorEx(ImGuiSeparatorFlags_Horizontal); @@ -99,7 +100,6 @@ namespace SHADE } if (ImGui::IsKeyDown(ImGuiKey_LeftCtrl) && ImGui::IsKeyDown(ImGuiKey_LeftShift) && ImGui::IsKeyReleased(ImGuiKey_V)) { - const auto editor = SHSystemManager::GetSystem(); if (editor->selectedEntities.size() == 1) { PasteEntities(editor->selectedEntities.back()); @@ -141,16 +141,18 @@ namespace SHADE //#==============================================================# //|| Private Member Functions || //#==============================================================# - void SHHierarchyPanel::DrawMenuBar() const noexcept + void SHHierarchyPanel::DrawMenuBar() noexcept { if (ImGui::BeginMenuBar()) { auto size = ImGui::GetWindowSize(); auto g = ImGui::GetCurrentContext(); + + DrawHierarchyPanelFilter(); + ImGui::SetCursorPosX(size.x - g->Style.FramePadding.x * 15.0f); if (ImGui::SmallButton(ICON_MD_CLEAR_ALL)) { - auto editor = SHSystemManager::GetSystem(); editor->selectedEntities.clear(); } if (ImGui::IsItemHovered()) @@ -173,6 +175,56 @@ namespace SHADE } } + void SHHierarchyPanel::DrawHierarchyPanelFilter() noexcept + { + if(ImGui::InputTextWithHint("##hierarchyPanelFilter", "Filter", &filter)) + { + + } + ImGui::SameLine(); + if(ImGui::Button("x")) + { + filter.clear(); + } + } + + bool SHHierarchyPanel::EntityFilterCheck(SHSceneNode* entityNode) noexcept + { + if(!entityNode || filter.empty()) + return false; + + EntityID const eid = entityNode->GetEntityID(); + SHEntity* entity = SHEntityManager::GetEntityByID(eid); + + bool result = false; + + result |= SHStringUtilities::StringFindInsensitive(entity->name, filter) != std::string::npos; + + if(SHStringUtilities::StringFindInsensitive(rttr::type::get().get_name().data(), filter) != std::string::npos) + { + result |= SHComponentManager::HasComponent(eid); + } + //result |= SHStringUtilities::StringFindInsensitive(rttr::type::get().get_name().data(), filter) != std::string::npos; + //result |= SHStringUtilities::StringFindInsensitive(rttr::type::get().get_name().data(), filter) != std::string::npos; + //result |= SHStringUtilities::StringFindInsensitive(rttr::type::get().get_name().data(), filter) != std::string::npos; + //result |= SHStringUtilities::StringFindInsensitive(rttr::type::get().get_name().data(), filter) != std::string::npos; + //result |= SHStringUtilities::StringFindInsensitive(rttr::type::get().get_name().data(), filter) != std::string::npos; + //result |= SHStringUtilities::StringFindInsensitive(rttr::type::get().get_name().data(), filter) != std::string::npos; + //result |= SHStringUtilities::StringFindInsensitive(rttr::type::get().get_name().data(), filter) != std::string::npos; + //result |= SHStringUtilities::StringFindInsensitive(rttr::type::get().get_name().data(), filter) != std::string::npos; + //result |= SHStringUtilities::StringFindInsensitive(rttr::type::get().get_name().data(), filter) != std::string::npos; + //result |= SHStringUtilities::StringFindInsensitive(rttr::type::get().get_name().data(), filter) != std::string::npos; + + //std::vector const& children = entityNode->GetChildren(); + + //for (auto const& child : children) + //{ + // result |= EntityFilterCheck(child); + //} + + return result; + } + ImRect SHHierarchyPanel::RecursivelyDrawEntityNode(SHSceneNode* const currentNode) { if (currentNode == nullptr) @@ -189,21 +241,39 @@ namespace SHADE scrollTo = MAX_EID; } - auto editor = SHSystemManager::GetSystem(); + auto* entity = SHEntityManager::GetEntityByID(eid); const bool isSelected = (std::ranges::find(editor->selectedEntities, eid) != editor->selectedEntities.end()); - const ImGuiTreeNodeFlags nodeFlags = ((isSelected) ? ImGuiTreeNodeFlags_Selected : 0) | ((children.empty()) ? ImGuiTreeNodeFlags_Leaf : ImGuiTreeNodeFlags_OpenOnArrow); - - //bool highlighted = false; - //if(highlighted) + bool highlighted = false; + //if(!filter.empty()) //{ - // ImGui::PushStyleColor(ImGuiCol_Text, highlightedColor); + // highlighted = EntityFilterCheck(currentNode); + // if (highlighted) + // { + // ImGui::PushStyleColor(ImGuiCol_Text, highlightedColor); + // + // ImGui::SetNextItemOpen(true); + // + // + // } + // else + // { + // + // } //} - auto* entity = SHEntityManager::GetEntityByID(currentNode->GetEntityID()); + const ImGuiTreeNodeFlags nodeFlags = ((isSelected) ? ImGuiTreeNodeFlags_Selected : 0) | ((children.empty()) ? ImGuiTreeNodeFlags_Leaf : ImGuiTreeNodeFlags_OpenOnArrow); + + //Draw Node - bool isNodeOpen = ImGui::TreeNodeEx(reinterpret_cast(entity), nodeFlags, "%u: %s", SHEntityManager::GetEntityIndex(eid), entity->name.c_str()); + bool isNodeOpen = ImGui::TreeNodeEx(reinterpret_cast(eid), nodeFlags, "%u: %s", SHEntityManager::GetEntityIndex(eid), entity->name.c_str()); + + if (highlighted) + { + ImGui::PopStyleColor(); + } + const ImRect nodeRect = ImRect(ImGui::GetItemRectMin(), ImGui::GetItemRectMax()); //Check For Begin Drag @@ -336,6 +406,7 @@ namespace SHADE drawList->AddLine(vertLineStart, vertLineEnd, treeLineColor, 2); ImGui::TreePop(); } + return nodeRect; } @@ -350,7 +421,6 @@ namespace SHADE std::vector entitiesToParent = CleanUpEIDList(entities); - //auto const editor = SHSystemManager::GetSystem(); SHEntityParentCommand::EntityParentData entityParentData; std::vector parentedEIDS; for (auto const& eid : entitiesToParent) @@ -371,7 +441,7 @@ namespace SHADE void SHHierarchyPanel::SelectRangeOfEntities(EntityID beginEID, EntityID endEID) { bool startSelecting = false; bool endSelecting = false; - auto const editor = SHSystemManager::GetSystem(); + editor->selectedEntities.clear(); auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); sceneGraph.Traverse([&](SHSceneNode* nodePtr) @@ -403,7 +473,6 @@ namespace SHADE void SHHierarchyPanel::SelectAllEntities() { - const auto editor = SHSystemManager::GetSystem(); editor->selectedEntities.clear(); auto const& sceneGraph = SHSceneManager::GetCurrentSceneGraph(); sceneGraph.Traverse([&](SHSceneNode* nodePtr) @@ -415,7 +484,6 @@ namespace SHADE void SHHierarchyPanel::CopySelectedEntities() { - const auto editor = SHSystemManager::GetSystem(); std::vector entitiesToCopy = CleanUpEIDList(editor->selectedEntities); SHClipboardUtilities::WriteToClipboard(SHSerialization::SerializeEntitiesToString(entitiesToCopy)); } @@ -428,7 +496,6 @@ namespace SHADE void SHHierarchyPanel::DeleteSelectedEntities() { - const auto editor = SHSystemManager::GetSystem(); std::vector entitiesToDelete = CleanUpEIDList(editor->selectedEntities); SHCommandManager::PerformCommand(std::make_shared(entitiesToDelete)); } diff --git a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h index 9278a0a3..c6670948 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h +++ b/SHADE_Engine/src/Editor/EditorWindow/HierarchyPanel/SHHierarchyPanel.h @@ -10,6 +10,8 @@ #include "imgui_internal.h" #include "ECS_Base/SHECSMacros.h" #include "Editor/EditorWindow/SHEditorWindow.h" +#include "ECS_Base/Entity/SHEntity.h" + namespace SHADE { class SHSceneNode; @@ -24,7 +26,11 @@ namespace SHADE void Exit() override; void SetScrollTo(EntityID eid); private: - void DrawMenuBar() const noexcept; + void DrawMenuBar() noexcept; + void DrawHierarchyPanelFilter() noexcept; + + bool EntityFilterCheck(SHSceneNode* entityNode) noexcept; + ImRect RecursivelyDrawEntityNode(SHSceneNode* const); void CreateChildEntity(EntityID parentEID) const noexcept; void ParentSelectedEntities(EntityID parentEID, std::vector const& entities) noexcept; diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp index 45964930..3e1fdc44 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorComponentView.hpp @@ -77,7 +77,7 @@ namespace SHADE ImGui::PushID(SHFamilyID::GetID()); SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active"); ImGui::SameLine(); - if (ImGui::CollapsingHeader(componentType.get_name().data())) + if (ImGui::CollapsingHeader(componentType.get_name().data(), ImGuiTreeNodeFlags_DefaultOpen)) { DrawContextMenu(component); auto const& properties = componentType.get_properties(); @@ -234,7 +234,7 @@ namespace SHADE const auto componentType = rttr::type::get(); SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active"); ImGui::SameLine(); - if (ImGui::CollapsingHeader(componentType.get_name().data())) + if (ImGui::CollapsingHeader(componentType.get_name().data(), ImGuiTreeNodeFlags_DefaultOpen)) { DrawContextMenu(component); @@ -328,7 +328,7 @@ namespace SHADE const auto componentType = rttr::type::get(*component); SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active"); ImGui::SameLine(); - if (ImGui::CollapsingHeader(componentType.get_name().data())) + if (ImGui::CollapsingHeader(componentType.get_name().data(), ImGuiTreeNodeFlags_DefaultOpen)) { DrawContextMenu(component); @@ -446,7 +446,7 @@ namespace SHADE const auto componentType = rttr::type::get(*component); SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active"); ImGui::SameLine(); - if (ImGui::CollapsingHeader(componentType.get_name().data())) + if (ImGui::CollapsingHeader(componentType.get_name().data(), ImGuiTreeNodeFlags_DefaultOpen)) { DrawContextMenu(component); @@ -478,7 +478,7 @@ namespace SHADE const auto componentType = rttr::type::get(*component); SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active"); ImGui::SameLine(); - if (ImGui::CollapsingHeader(componentType.get_name().data())) + if (ImGui::CollapsingHeader(componentType.get_name().data(), ImGuiTreeNodeFlags_DefaultOpen)) { DrawContextMenu(component); Handle const& mesh = component->GetMesh(); @@ -536,7 +536,7 @@ namespace SHADE const auto componentType = rttr::type::get(*component); SHEditorWidgets::CheckBox("##IsActive", [component]() {return component->isActive; }, [component](bool const& active) {component->isActive = active; }, "Is Component Active"); ImGui::SameLine(); - if (ImGui::CollapsingHeader(componentType.get_name().data())) + if (ImGui::CollapsingHeader(componentType.get_name().data(), ImGuiTreeNodeFlags_DefaultOpen)) { DrawContextMenu(component); Handle const& font = component->GetFont(); diff --git a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp index ed6ea6bb..55de44cc 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/Inspector/SHEditorInspector.cpp @@ -94,7 +94,6 @@ namespace SHADE SHEditorWindow::Update(); if (Begin()) { - auto editor = SHSystemManager::GetSystem(); if (editor && !editor->selectedEntities.empty()) { EntityID const& eid = editor->selectedEntities[0]; diff --git a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp index 5014dbdd..3fe9ceb5 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/MenuBar/SHEditorMenuBar.cpp @@ -110,7 +110,7 @@ namespace SHADE { ImGui::BeginMenuBar(); ImGui::SetCursorPosX(ImGui::GetContentRegionAvail().x * 0.5f - 80.f); - const auto editor = SHSystemManager::GetSystem(); + ImGui::BeginDisabled(editor->editorState == SHEditor::State::PLAY); if(ImGui::SmallButton(ICON_MD_PLAY_ARROW)) { @@ -165,16 +165,18 @@ namespace SHADE { if (ImGui::Selectable("New Scene")) { - SHSystemManager::GetSystem()->NewScene(); + editor->NewScene(); } if (ImGui::Selectable("Save")) { - SHSystemManager::GetSystem()->SaveScene(); + editor->SaveScene(); } + ImGui::BeginDisabled(true); if (ImGui::Selectable("Load")) { //SHSystemManager::GetSystem()->LoadScene() } + ImGui::EndDisabled(); ImGui::EndMenu(); } } @@ -211,7 +213,7 @@ namespace SHADE auto* scriptEngine = static_cast(SHSystemManager::GetSystem()); scriptEngine->OpenSolution(); } - ImGui::BeginDisabled(SHSystemManager::GetSystem()->editorState != SHEditor::State::STOP); + ImGui::BeginDisabled(editor->editorState != SHEditor::State::STOP); if (ImGui::Selectable("Build Scripts - Debug")) { auto* scriptEngine = static_cast(SHSystemManager::GetSystem()); @@ -252,7 +254,6 @@ namespace SHADE { if (ImGui::Selectable(style.to_string().c_str())) { - if (auto editor = SHSystemManager::GetSystem()) editor->SetStyle(style.convert()); } } diff --git a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.cpp b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.cpp index 5f00cc37..05059336 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.cpp @@ -7,6 +7,8 @@ //|| SHADE Includes || //#==============================================================# #include "SHEditorWindow.h" +#include "ECS_Base/Managers/SHSystemManager.h" +#include "Editor/SHEditor.h" //#==============================================================# //|| Library Includes || @@ -21,6 +23,7 @@ namespace SHADE SHEditorWindow::SHEditorWindow(std::string_view const& name, ImGuiWindowFlags const& inFlags) :isOpen(true), isWindowHovered(false), windowName(name), windowFlags(inFlags), io(ImGui::GetIO()) { + editor = SHSystemManager::GetSystem(); } void SHEditorWindow::Init() diff --git a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.h b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.h index faacd8f2..9b932827 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.h +++ b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindow.h @@ -12,9 +12,9 @@ //#==============================================================# struct ImGuiIO; typedef int ImGuiWindowFlags; - namespace SHADE { + class SHEditor; class SHEditorWindow { public: @@ -38,6 +38,6 @@ namespace SHADE ImGuiWindowFlags windowFlags = 0; ImGuiIO& io; - + SHEditor* editor; };//class SHEditorWindow }//namespace SHADE diff --git a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowManager.cpp b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowManager.cpp index 420b5414..a63e659b 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowManager.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowManager.cpp @@ -4,5 +4,7 @@ namespace SHADE { SHEditorWindowManager::EditorWindowMap SHEditorWindowManager::editorWindows{}; + SHEditorWindowManager::PopupWindowMap SHEditorWindowManager::popupWindows{}; SHEditorWindowManager::EditorWindowID SHEditorWindowManager::windowCount{}; + SHEditorWindowManager::EditorWindowID SHEditorWindowManager::popupWindowCount{}; } diff --git a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowManager.h b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowManager.h index 60730f0e..062f864a 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowManager.h +++ b/SHADE_Engine/src/Editor/EditorWindow/SHEditorWindowManager.h @@ -3,6 +3,7 @@ #include #include #include "SHEditorWindow.h" +#include "SHPopUpWindow.h" #include "Tools/Logger/SHLog.h" namespace SHADE @@ -16,6 +17,10 @@ namespace SHADE using EditorWindowID = uint8_t; using EditorWindowPtr = std::unique_ptr; using EditorWindowMap = std::unordered_map; + + using PopupWindowPtr = std::unique_ptr; + using PopupWindowMap = std::unordered_map; + /** * @brief Get ID for the Editor Window Type * @@ -67,10 +72,63 @@ namespace SHADE return reinterpret_cast(editorWindows[GetEditorWindowID()].get()); } + /** + * @brief Get ID for the Popup Window Type + * + * @tparam T Type of Popup Window + * @return EditorWindowID ID of Popup Window Type + */ + template , bool> = true> + static EditorWindowID GetPopupWindowID() + { + static EditorWindowID id; + static bool idCreated = false; + if (!idCreated) + { + id = popupWindowCount++; + idCreated = true; + } + return id; + } + + /** + * @brief Create an Popup Window + * + * @tparam T Type of Popup Window to create + */ + template , bool> = true> + static void CreatePopupWindow() + { + static bool isCreated = false; + if (!isCreated) + { + popupWindows[GetPopupWindowID()] = std::make_unique(); + isCreated = true; + } + else + { + SHLog::Warning("Attempt to create duplicate of Popup window type"); + } + } + + /** + * @brief Get pointer to the Editor Window + * + * @tparam T Type of editor window to retrieve + * @return T* Pointer to the editor window + */ + template , bool> = true> + static T* GetPopupWindow() + { + return reinterpret_cast(popupWindows[GetPopupWindowID()].get()); + } + static EditorWindowMap editorWindows; + static PopupWindowMap popupWindows; private: // Number of windows; used for Editor Window ID Generation static EditorWindowID windowCount; + static EditorWindowID popupWindowCount; // Map of Editor Windows friend class SHEditor; }; diff --git a/SHADE_Engine/src/Editor/EditorWindow/SHPopUpWindow.cpp b/SHADE_Engine/src/Editor/EditorWindow/SHPopUpWindow.cpp new file mode 100644 index 00000000..f82a7495 --- /dev/null +++ b/SHADE_Engine/src/Editor/EditorWindow/SHPopUpWindow.cpp @@ -0,0 +1,21 @@ +#include "SHpch.h" +#include "SHPopUpWindow.h" +#include "ECS_Base/Managers/SHSystemManager.h" +#include "Editor/SHEditor.h" + +namespace SHADE +{ + SHPopUpWindow::SHPopUpWindow(std::string_view const& name, bool modal, ImGuiPopupFlags inPopupFlags, ImGuiWindowFlags inWindowFlags) + :editor(nullptr), windowName(name), popupFlags(inPopupFlags), windowFlags(inWindowFlags), isOpen(false), isModal(modal) + { + editor = SHSystemManager::GetSystem(); + } + + bool SHPopUpWindow::Begin() + { + if (isOpen) + ImGui::OpenPopup(windowName.data(), popupFlags); + + return isModal ? ImGui::BeginPopupModal(windowName.data(), &isOpen, windowFlags) : ImGui::BeginPopup(windowName.data(), windowFlags); + } +} \ No newline at end of file diff --git a/SHADE_Engine/src/Editor/EditorWindow/SHPopUpWindow.h b/SHADE_Engine/src/Editor/EditorWindow/SHPopUpWindow.h new file mode 100644 index 00000000..b69b3e99 --- /dev/null +++ b/SHADE_Engine/src/Editor/EditorWindow/SHPopUpWindow.h @@ -0,0 +1,31 @@ +#pragma once + +//#==============================================================# +//|| STL Includes || +//#==============================================================# +#include +#include +#include "SH_API.h" + +namespace SHADE +{ + class SHEditor; + class SHPopUpWindow + { + public: + SHPopUpWindow(std::string_view const& name, bool modal, ImGuiPopupFlags inPopupFlags, ImGuiWindowFlags inWindowFlags); + virtual ~SHPopUpWindow() = default; + virtual void Draw(){}; + + bool isOpen; + + protected: + virtual bool Begin(); + + SHEditor* editor; + std::string_view windowName; + ImGuiPopupFlags popupFlags; + ImGuiWindowFlags windowFlags; + bool isModal; + }; +} \ No newline at end of file diff --git a/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp b/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp index 93f4a615..8c32b1c5 100644 --- a/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp +++ b/SHADE_Engine/src/Editor/EditorWindow/ViewportWindow/SHEditorViewport.cpp @@ -35,7 +35,6 @@ namespace SHADE { SHEditorWindow::Update(); auto camSystem = SHSystemManager::GetSystem(); - SHEditor* editor = SHSystemManager::GetSystem(); if (!editor->selectedEntities.empty()) { diff --git a/SHADE_Engine/src/Editor/SHEditor.cpp b/SHADE_Engine/src/Editor/SHEditor.cpp index 14b37263..06e2da56 100644 --- a/SHADE_Engine/src/Editor/SHEditor.cpp +++ b/SHADE_Engine/src/Editor/SHEditor.cpp @@ -32,6 +32,9 @@ #include "EditorWindow/SHEditorWindowManager.h" #include "EditorWindow/SHEditorWindowIncludes.h" +#include "EditorWindow/SHPopUpWindow.h" +#include "EditorWindow/EditorPopups/SHEditorPopups.h" + //#==============================================================# //|| Library Includes || //#==============================================================# @@ -98,15 +101,18 @@ namespace SHADE //Add editor windows SHEditorWindowManager::CreateEditorWindow(); - SHEditorWindowManager::CreateEditorWindow(); - SHEditorWindowManager::CreateEditorWindow(); SHEditorWindowManager::CreateEditorWindow(); SHEditorWindowManager::CreateEditorWindow(); SHEditorWindowManager::CreateEditorWindow(); SHEditorWindowManager::CreateEditorWindow(); + SHEditorWindowManager::CreateEditorWindow(); + SHEditorWindowManager::CreateEditorWindow(); SHEditorWindowManager::CreateEditorWindow(); + //Add popup windows + SHEditorWindowManager::CreatePopupWindow(); + io = &ImGui::GetIO(); io->ConfigFlags |= ImGuiConfigFlags_NavEnableKeyboard; // Enable Keyboard Controls @@ -150,7 +156,7 @@ namespace SHADE { (void)dt; NewFrame(); - for (const auto& window : SHEditorWindowManager::editorWindows | std::views::values) + for (auto const& window : SHEditorWindowManager::editorWindows | std::views::values) { if(window->isOpen) { @@ -158,7 +164,11 @@ namespace SHADE } } - RenderSceneNamePrompt(); + for(auto const& popupWindow : SHEditorWindowManager::popupWindows | std::views::values) + { + popupWindow->Draw(); + } + RenderUnsavedChangesPrompt(); //PollPicking(); @@ -177,37 +187,6 @@ namespace SHADE } } - void SHEditor::RenderSceneNamePrompt() noexcept - { - if(isSceneNamePromptOpen) - { - ImGui::OpenPopup(sceneNamePromptName.data()); - } - - if(ImGui::BeginPopupModal(sceneNamePromptName.data(), &isSceneNamePromptOpen)) - { - static std::string newSceneName{}; - ImGui::Text("Enter new scene name"); - ImGui::InputText("##name", &newSceneName); - ImGui::BeginDisabled(newSceneName.empty()); - if(ImGui::Button("Save")) - { - SaveScene(newSceneName); - newSceneName.clear(); - isSceneNamePromptOpen = false; - ImGui::CloseCurrentPopup(); - } - ImGui::EndDisabled(); - ImGui::SameLine(); - if(ImGui::Button("Cancel")) - { - isSceneNamePromptOpen = false; - ImGui::CloseCurrentPopup(); - } - ImGui::EndPopup(); - } - } - void SHEditor::RenderUnsavedChangesPrompt() noexcept { if(isUnsavedChangesPromptOpen) @@ -220,12 +199,12 @@ namespace SHADE ImGui::Text("You have unsaved changes!"); if(ImGui::Button("Save")) { - isSceneNamePromptOpen = true; + SHEditorWindowManager::GetPopupWindow()->isOpen = true; } ImGui::SameLine(); if(ImGui::Button("Cancel")) { - isUnsavedChangesPromptOpen = false; + SHEditorWindowManager::GetPopupWindow()->isOpen = true; ImGui::CloseCurrentPopup(); } } @@ -563,7 +542,7 @@ namespace SHADE if (newSceneName.empty()) { //Prompt for scene name - isSceneNamePromptOpen = true; + SHEditorWindowManager::GetPopupWindow()->isOpen = true; return false; } //Else We have a new name @@ -644,7 +623,7 @@ namespace SHADE editorState = SHEditor::State::STOP; SHCommandManager::SwapStacks(); SHEventManager::BroadcastEvent(STATE_CHANGE_EVENT, SH_EDITOR_ON_STOP_EVENT); - LoadScene(SHSceneManager::GetCurrentSceneAssetID()); + LoadScene(editorConfig->workingSceneID); } void SHEditor::ProcessShortcuts() diff --git a/SHADE_Engine/src/Editor/SHEditor.h b/SHADE_Engine/src/Editor/SHEditor.h index 103f834f..d616c096 100644 --- a/SHADE_Engine/src/Editor/SHEditor.h +++ b/SHADE_Engine/src/Editor/SHEditor.h @@ -37,8 +37,6 @@ namespace SHADE class SHVkCommandBuffer; class SHVkCommandPool; - - /** * @brief SHEditor static class contains editor variables and implementation of editor functions. * @@ -144,8 +142,6 @@ namespace SHADE */ void Render(); - void RenderSceneNamePrompt() noexcept; - void RenderUnsavedChangesPrompt() noexcept; void InitLayout() noexcept; @@ -156,8 +152,6 @@ namespace SHADE SHEventHandle onEditorStateChanged(SHEventPtr eventPtr); - bool isSceneNamePromptOpen = false; - bool isUnsavedChangesPromptOpen = false; static constexpr std::string_view sceneNamePromptName = "Save scene as..."; diff --git a/SHADE_Engine/src/Editor/SHEditorWidgets.hpp b/SHADE_Engine/src/Editor/SHEditorWidgets.hpp index 441f95aa..f3dfe194 100644 --- a/SHADE_Engine/src/Editor/SHEditorWidgets.hpp +++ b/SHADE_Engine/src/Editor/SHEditorWidgets.hpp @@ -13,6 +13,8 @@ #include "Command/SHCommandManager.h" #include "SHImGuiHelpers.hpp" #include "SH_API.h" +#include "Assets/SHAssetMacros.h" +#include "ECS_Base/SHECSMacros.h" //#==============================================================# //|| Library Includes || @@ -454,7 +456,33 @@ namespace SHADE ImGui::BeginGroup(); ImGui::PushID(label.data()); TextLabel(label); - const bool hasChange = ImGui::InputScalar("##dragScalar", data_type, &value); + bool hasChange = ImGui::DragScalar("##dragScalar", data_type, &value); + if constexpr(std::is_same_v) //EID or Resource + { + if (SHDragDrop::BeginTarget()) + { + if(AssetID * payload = SHDragDrop::AcceptPayload(SHDragDrop::DRAG_RESOURCE)) + { + value = *payload; + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); + hasChange = true; + SHDragDrop::EndTarget(); + } + else if (std::vector* payload = SHDragDrop::AcceptPayload>(SHDragDrop::DRAG_EID)) + { + value = payload->back(); + SHCommandManager::PerformCommand(std::reinterpret_pointer_cast(std::make_shared>(get(), value, set)), false); + hasChange = true; + SHDragDrop::EndTarget(); + } + if(hasChange) + { + ImGui::PopID(); + ImGui::EndGroup(); + return true; + } + } + } static bool startRecording = false; if (hasChange) { diff --git a/SHADE_Engine/src/Serialization/SHSerialization.cpp b/SHADE_Engine/src/Serialization/SHSerialization.cpp index cc081413..6af13b17 100644 --- a/SHADE_Engine/src/Serialization/SHSerialization.cpp +++ b/SHADE_Engine/src/Serialization/SHSerialization.cpp @@ -11,16 +11,8 @@ #include #include "Assets/Asset Types/SHSceneAsset.h" -#include "Camera/SHCameraComponent.h" -#include "Camera/SHCameraArmComponent.h" -#include "Math/Transform/SHTransformComponent.h" -#include "Graphics/MiddleEnd/Interface/SHRenderable.h" -#include "Physics/Interface/SHRigidBodyComponent.h" -#include "UI/SHCanvasComponent.h" -#include "UI/SHButtonComponent.h" -#include "UI/SHToggleButtonComponent.h" +#include "Common/SHAllComponents.h" #include "ECS_Base/Managers/SHSystemManager.h" -#include "Graphics/MiddleEnd/Lights/SHLightComponent.h" #include "Scripting/SHScriptEngine.h" #include "Tools/FileIO/SHFileIO.h" diff --git a/SHADE_Engine/src/Serialization/SHYAMLConverters.h b/SHADE_Engine/src/Serialization/SHYAMLConverters.h index 58268b57..2e2d45f4 100644 --- a/SHADE_Engine/src/Serialization/SHYAMLConverters.h +++ b/SHADE_Engine/src/Serialization/SHYAMLConverters.h @@ -1,5 +1,7 @@ #pragma once #include "Graphics/MiddleEnd/Interface/SHRenderable.h" +#include "Physics/Interface/SHColliderComponent.h" +#include "Graphics/MiddleEnd/TextRendering/SHTextRenderableComponent.h" #include "Graphics/MiddleEnd/Materials/SHMaterialSpec.h" #include "Math/Geometry/SHBox.h" #include "Math/Geometry/SHSphere.h" @@ -11,8 +13,6 @@ #include "Graphics/MiddleEnd/Interface/SHMaterial.h" #include "Graphics/MiddleEnd/Interface/SHMaterialInstance.h" #include "SHSerializationTools.h" -#include "Physics/Interface/SHColliderComponent.h" -#include "Graphics/MiddleEnd/TextRendering/SHTextRenderableComponent.h" #include "Graphics/MiddleEnd/TextRendering/SHFont.h" #include "Physics/Collision/SHCollisionTagMatrix.h" diff --git a/SHADE_Engine/src/Tools/Utilities/SHStringUtilities.cpp b/SHADE_Engine/src/Tools/Utilities/SHStringUtilities.cpp index b9698071..f547da6c 100644 --- a/SHADE_Engine/src/Tools/Utilities/SHStringUtilities.cpp +++ b/SHADE_Engine/src/Tools/Utilities/SHStringUtilities.cpp @@ -13,6 +13,7 @@ of DigiPen Institute of Technology is prohibited. #include // Primary Header #include "SHStringUtilities.h" +#include namespace SHADE { @@ -50,5 +51,12 @@ namespace SHADE { return std::system_category().message(errorCode); } + + size_t SHStringUtilities::StringFindInsensitive(std::string str, std::string search, size_t pos) + { + std::transform(str.begin(), str.end(), str.begin(), [](char c) {return static_cast(std::tolower(c)); }); + std::transform(search.begin(), search.end(), search.begin(), [](char c) {return static_cast(std::tolower(c)); }); + return str.find(search, pos); + } } \ No newline at end of file diff --git a/SHADE_Engine/src/Tools/Utilities/SHStringUtilities.h b/SHADE_Engine/src/Tools/Utilities/SHStringUtilities.h index bac83b07..697e19f2 100644 --- a/SHADE_Engine/src/Tools/Utilities/SHStringUtilities.h +++ b/SHADE_Engine/src/Tools/Utilities/SHStringUtilities.h @@ -4,9 +4,9 @@ \par email: kahwei.tng\@digipen.edu \date Nov 29, 2021 \brief Contains the declaration of functions for working with files and folders. - + Copyright (C) 2021 DigiPen Institute of Technology. -Reproduction or disclosure of this file or its contents without the prior written consent +Reproduction or disclosure of this file or its contents without the prior written consent of DigiPen Institute of Technology is prohibited. *//*************************************************************************************/ #pragma once @@ -16,66 +16,68 @@ of DigiPen Institute of Technology is prohibited. namespace SHADE { - /// - /// Contains useful functions for operating on strings. - /// - class SHStringUtilities - { - public: - /*-----------------------------------------------------------------------------*/ - /* Utility Functions */ - /*-----------------------------------------------------------------------------*/ - - /// - /// Splits a string separated by a specified delimiter into a vector of strings. - /// - /// Internal type of each element in the string. - /// Read only reference to the string to split. - /// Read only reference to the delimiter. - /// Vector of strings that have been split. - template - static std::vector> Split(const std::basic_string& str, const T& delim); - /// - /// Splits a string separated by a specified delimiter into a vector of strings. - /// Overload of Split() to allow for string literals to be accepted. - /// - /// Read only reference to the string to split. - /// Read only reference to the delimiter. - /// Vector of strings that have been split. - static std::vector Split(const std::string& str, const char& delim); - /// - /// Splits a string separated by a specified delimiter into a vector of strings. - /// Overload of Split() to allow for wide string literals to be accepted. - /// - /// Read only reference to the string to split. - /// Read only reference to the delimiter. - /// Vector of strings that have been split. - static std::vector Split(const std::wstring& str, const wchar_t& delim); - /// - /// Converts a wstring to a string. - /// - /// wstring to convert. - /// The converted wstring in string form. - static std::string WstrToStr(const std::wstring& wstr); - /// - /// Converts a string to a wstring. - /// - /// string to convert. - /// The converted string in wstring form. - static std::wstring StrToWstr(const std::string& str); - /// - /// Retrieves the error message associated with a Win32 error code. - /// - /// Win32 error code to decode. - /// String that represents the Win32 error. - static std::string GetWin32ErrorMessage(unsigned long errorCode); + /// + /// Contains useful functions for operating on strings. + /// + class SHStringUtilities + { + public: + /*-----------------------------------------------------------------------------*/ + /* Utility Functions */ + /*-----------------------------------------------------------------------------*/ - private: - /*-------------------------------------------------------------------------------*/ - /* Constructors/Destructors */ - /*-------------------------------------------------------------------------------*/ - SHStringUtilities() = delete; - }; + /// + /// Splits a string separated by a specified delimiter into a vector of strings. + /// + /// Internal type of each element in the string. + /// Read only reference to the string to split. + /// Read only reference to the delimiter. + /// Vector of strings that have been split. + template + static std::vector> Split(const std::basic_string& str, const T& delim); + /// + /// Splits a string separated by a specified delimiter into a vector of strings. + /// Overload of Split() to allow for string literals to be accepted. + /// + /// Read only reference to the string to split. + /// Read only reference to the delimiter. + /// Vector of strings that have been split. + static std::vector Split(const std::string& str, const char& delim); + /// + /// Splits a string separated by a specified delimiter into a vector of strings. + /// Overload of Split() to allow for wide string literals to be accepted. + /// + /// Read only reference to the string to split. + /// Read only reference to the delimiter. + /// Vector of strings that have been split. + static std::vector Split(const std::wstring& str, const wchar_t& delim); + /// + /// Converts a wstring to a string. + /// + /// wstring to convert. + /// The converted wstring in string form. + static std::string WstrToStr(const std::wstring& wstr); + /// + /// Converts a string to a wstring. + /// + /// string to convert. + /// The converted string in wstring form. + static std::wstring StrToWstr(const std::string& str); + /// + /// Retrieves the error message associated with a Win32 error code. + /// + /// Win32 error code to decode. + /// String that represents the Win32 error. + static std::string GetWin32ErrorMessage(unsigned long errorCode); + + static size_t StringFindInsensitive(std::string str, std::string search, size_t pos = 0); + + private: + /*-------------------------------------------------------------------------------*/ + /* Constructors/Destructors */ + /*-------------------------------------------------------------------------------*/ + SHStringUtilities() = delete; + }; } #include "SHStringUtilities.hpp"