diff --git a/CMakeLists.txt b/CMakeLists.txt index ef77ca7..45476d1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,16 +8,27 @@ set(CMAKE_CXX_STANDARD_REQUIRED ON) # --- Compiler flags --- if(MSVC) - add_compile_definitions(GLM_ENABLE_EXPERIMENTAL) + add_compile_definitions(GLM_ENABLE_EXPERIMENTAL WIN32_LEAN_AND_MEAN NOMINMAX) add_compile_options(/W4 /Zi) else() - add_compile_definitions(GLM_ENABLE_EXPERIMENTAL) - add_compile_options(-Wall -g) - add_compile_options(-O2 -static -static-libstdc++ -static-libgcc) + add_compile_definitions(GLM_ENABLE_EXPERIMENTAL WIN32_LEAN_AND_MEAN NOMINMAX) + add_compile_options(-Wall -g -O2 -static -static-libstdc++ -static-libgcc) endif() -# --- Include directories --- -include_directories( +# --- Gather source files --- +file(GLOB_RECURSE SOURCE_FILES + ${CMAKE_SOURCE_DIR}/src/src/*.cpp + ${CMAKE_SOURCE_DIR}/src/src/*.c + ${CMAKE_SOURCE_DIR}/src/vendor/*.cpp + ${CMAKE_SOURCE_DIR}/src/vendor/*.c + ${CMAKE_SOURCE_DIR}/src/include/lua/*.c +) + +# --- Define target --- +add_executable(${PROJECT_NAME} ${SOURCE_FILES}) + +# --- Include directories for this target --- +target_include_directories(${PROJECT_NAME} PRIVATE ${CMAKE_SOURCE_DIR}/src/include ${CMAKE_SOURCE_DIR}/src/include/lua ${CMAKE_SOURCE_DIR}/src/vendor @@ -29,27 +40,17 @@ include_directories( ${CMAKE_SOURCE_DIR}/src/vendor/miniaudio ) -# --- Gather source files --- -file(GLOB_RECURSE SOURCE_FILES - ${CMAKE_SOURCE_DIR}/src/src/*.cpp - ${CMAKE_SOURCE_DIR}/src/src/*.c - ${CMAKE_SOURCE_DIR}/src/vendor/*.cpp - ${CMAKE_SOURCE_DIR}/src/vendor/*.c - ${CMAKE_SOURCE_DIR}/src/include/lua/*.c -) - - -# --- Define target --- -add_executable(${PROJECT_NAME} ${SOURCE_FILES}) - # --- Link libraries --- target_link_libraries(${PROJECT_NAME} PRIVATE glfw3 glew32 opengl32 gdi32 - yaml-cpp comdlg32 + ole32 + shell32 + uuid + yaml-cpp ssl crypto dbghelp @@ -57,7 +58,7 @@ target_link_libraries(${PROJECT_NAME} PRIVATE freetype ) -# --- Output dir --- +# --- Output directory --- set_target_properties(${PROJECT_NAME} PROPERTIES RUNTIME_OUTPUT_DIRECTORY "${CMAKE_SOURCE_DIR}/src/build" ) diff --git a/imgui.ini b/imgui.ini index 2e7c451..82f4e72 100644 --- a/imgui.ini +++ b/imgui.ini @@ -10,40 +10,40 @@ Collapsed=1 [Window][WindowOverViewport_11111111] Pos=0,19 -Size=1280,701 +Size=1920,1158 Collapsed=0 [Window][Inspector] -Pos=913,19 -Size=367,163 +Pos=1553,19 +Size=367,537 Collapsed=0 DockId=0x0000001B,0 [Window][Scene Tree] Pos=0,19 -Size=341,268 +Size=341,444 Collapsed=0 DockId=0x0000000F,0 [Window][Viewport] Pos=343,19 -Size=568,202 +Size=1208,659 Collapsed=0 DockId=0x00000017,0 [Window][##MainMenuBar] -Size=1280,19 +Size=1920,19 Collapsed=0 [Window][Performance Info] -Pos=1107,223 -Size=173,268 +Pos=1628,680 +Size=292,268 Collapsed=0 DockId=0x00000019,0 [Window][Console] -Pos=343,223 -Size=716,497 +Pos=343,680 +Size=1207,497 Collapsed=0 DockId=0x00000013,0 @@ -78,8 +78,8 @@ Collapsed=0 DockId=0x00000015,1 [Window][Color Correction] -Pos=1107,493 -Size=173,227 +Pos=1628,950 +Size=292,227 Collapsed=0 DockId=0x0000001A,0 @@ -113,8 +113,8 @@ Collapsed=0 DockId=0x0000000E,0 [Window][Audio Output] -Pos=1061,223 -Size=44,497 +Pos=1552,680 +Size=74,497 Collapsed=0 DockId=0x00000014,0 @@ -125,8 +125,8 @@ Collapsed=0 DockId=0x0000000D,0 [Window][Resources] -Pos=0,289 -Size=341,431 +Pos=0,465 +Size=341,712 Collapsed=0 DockId=0x00000010,0 @@ -136,8 +136,8 @@ Size=550,695 Collapsed=0 [Window][Lua Globals] -Pos=913,184 -Size=367,37 +Pos=1553,558 +Size=367,120 Collapsed=0 DockId=0x0000001C,0 @@ -146,6 +146,11 @@ Pos=626,263 Size=536,391 Collapsed=0 +[Window][Create New Project] +Pos=298,22 +Size=600,209 +Collapsed=0 + [Table][0x96376740,2] RefScale=13 Column 0 Weight=1.0000 @@ -181,7 +186,7 @@ Column 1 Width=86 Column 2 Weight=1.0000 [Docking][Data] -DockSpace ID=0x11111111 Window=0x1BBC0F80 Pos=0,19 Size=1280,701 Split=X +DockSpace ID=0x11111111 Window=0x1BBC0F80 Pos=0,19 Size=1920,1158 Split=X DockNode ID=0x00000005 Parent=0x11111111 SizeRef=989,1158 Split=X DockNode ID=0x00000001 Parent=0x00000005 SizeRef=341,701 Split=Y Selected=0x12EF0F59 DockNode ID=0x00000003 Parent=0x00000001 SizeRef=342,637 Split=Y Selected=0x12EF0F59 @@ -190,7 +195,7 @@ DockSpace ID=0x11111111 Window=0x1BBC0F80 Pos=0,19 Size=1280,701 Spl DockNode ID=0x00000004 Parent=0x00000001 SizeRef=342,519 HiddenTabBar=1 Selected=0x36AF052B DockNode ID=0x00000002 Parent=0x00000005 SizeRef=1577,701 Split=Y Selected=0xC450F867 DockNode ID=0x00000007 Parent=0x00000002 SizeRef=606,659 Split=X Selected=0xC450F867 - DockNode ID=0x00000017 Parent=0x00000007 SizeRef=1208,860 CentralNode=1 Selected=0xC450F867 + DockNode ID=0x00000017 Parent=0x00000007 SizeRef=1208,860 CentralNode=1 HiddenTabBar=1 Selected=0xC450F867 DockNode ID=0x00000018 Parent=0x00000007 SizeRef=367,860 Split=Y Selected=0x36DC96AB DockNode ID=0x0000001B Parent=0x00000018 SizeRef=367,537 HiddenTabBar=1 Selected=0x36DC96AB DockNode ID=0x0000001C Parent=0x00000018 SizeRef=367,120 HiddenTabBar=1 Selected=0x8CFF897F diff --git a/src/src/Engine.cpp b/src/src/Engine.cpp index c34346c..9de8f04 100644 --- a/src/src/Engine.cpp +++ b/src/src/Engine.cpp @@ -570,7 +570,7 @@ void Engine::Init() - //ProjectManager::LoadProject("C:/Users/spenc/OneDrive/Desktop", "TestProject"); + ProjectManager::LoadProject("C:/Users/spenc/OneDrive/Desktop", "TestProject"); } core::types::Vec2 ScreenToWorld(const core::types::Vec2 &screenPos, const core::types::Vec2 &viewportSize, const core::types::Vec2 &cameraPos, float zoom) @@ -680,6 +680,8 @@ void Engine::Run() ImGui::NewFrame(); profiler.EndEngineSection(); + + profiler.BeginEngineSection("ImGui::DockSpaceOverViewport"); ImGui::DockSpaceOverViewport(ImGui::GetMainViewport()->ID); profiler.EndEngineSection(); @@ -701,29 +703,12 @@ void Engine::Run() Logger::Draw(); profiler.EndEngineSection(); - { - if (ImGui::BeginPopupModal("ConfirmClearScene", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) - { - ImGui::Text("Are you sure you want to clear the scene?"); - ImGui::Separator(); - if (ImGui::Button("Yes", ImVec2(120, 0))) - { - objects.clear(); - selected = nullptr; - ImGui::CloseCurrentPopup(); - } - ImGui::SameLine(); - - if (ImGui::Button("Cancel", ImVec2(120, 0))) - ImGui::CloseCurrentPopup(); - - ImGui::EndPopup(); - } - } profiler.BeginEngineSection("BeginMainMenuBar"); + bool OpenNewProjectMenu = false; + bool OpenClearSceneMenu = false; if (ImGui::BeginMainMenuBar()) { @@ -745,7 +730,8 @@ void Engine::Run() if (ImGui::BeginMenu("File")) { - if (ImGui::MenuItem("Save Scene to Project")) + + if (ImGui::MenuItem("Save Scene")) { std::string path = ProjectManager::GetCurrentAssetsPath() + "/Scenes/" + ProjectManager::GetCurrentProjectName() + ".cene"; @@ -766,9 +752,28 @@ void Engine::Run() SceneLoader::LoadScene(file); selected = nullptr; } + + ImGui::Separator(); - if (ImGui::MenuItem("Clear Scene")) - ImGui::OpenPopup("ConfirmClearScene"); + ImGui::Spacing(); + + + if (ImGui::MenuItem("Create New Project")) + { + OpenNewProjectMenu = true; + } + + + + + ImGui::Separator(); + ImGui::Spacing(); + + + if (ImGui::MenuItem("Clear Scene")) { + OpenClearSceneMenu = true; + } + ImGui::EndMenu(); } @@ -821,6 +826,39 @@ void Engine::Run() ImGui::EndMenu(); } + if (OpenNewProjectMenu) + { + Logger::LogDebug("Opened Popup"); + OpenNewProjectMenu = false; + ImGui::OpenPopup("Create New Project"); + } + + if (OpenClearSceneMenu) + { + OpenClearSceneMenu = false; + ImGui::OpenPopup("ConfirmClearScene"); + } + ProjectManager::ShowCreateProjectPopup(); + + if (ImGui::BeginPopupModal("ConfirmClearScene", nullptr, ImGuiWindowFlags_AlwaysAutoResize)) + { + ImGui::Text("Are you sure you want to clear the scene?"); + ImGui::Separator(); + + if (ImGui::Button("Yes", ImVec2(120, 0))) + { + objects.clear(); + selected = nullptr; + ImGui::CloseCurrentPopup(); + } + + ImGui::SameLine(); + + if (ImGui::Button("Cancel", ImVec2(120, 0))) + ImGui::CloseCurrentPopup(); + + ImGui::EndPopup(); + } { ImGuiStyle &style = ImGui::GetStyle(); float barW = ImGui::GetWindowSize().x; @@ -878,6 +916,9 @@ void Engine::Run() DrawAudioPlayingList(); DrawImGuiWindow(); + + + { PROFILE_ENGINE_SCOPE("Engine::DrawSceneTree"); diff --git a/src/src/core/functions/ProjectManager.cpp b/src/src/core/functions/ProjectManager.cpp index 28a1cdb..b85ae23 100644 --- a/src/src/core/functions/ProjectManager.cpp +++ b/src/src/core/functions/ProjectManager.cpp @@ -13,6 +13,8 @@ #include #include #include +#include + namespace fs = std::filesystem; @@ -23,70 +25,64 @@ std::string ProjectManager::s_defaultScene; -// Call this to open the popup: -// ImGui::OpenPopup("Create New Project"); -// ShowCreateProjectPopup(&open); -void ProjectManager::ShowCreateProjectPopup(bool* pOpen) +void ProjectManager::ShowCreateProjectPopup() { - // Keep static buffers across frames - static char nameBuf[128] = ""; + static char nameBuf[256] = ""; static char pathBuf[512] = ""; - // Center-popup and set a decent default size - ImGui::SetNextWindowSize({500, 0}, ImGuiCond_Appearing); - if (!ImGui::BeginPopupModal("Create New Project", pOpen, ImGuiWindowFlags_NoResize)) + ImGui::SetNextWindowSizeConstraints({ 0, 0 }, { 600, FLT_MAX }); + if (!ImGui::BeginPopupModal( + "Create New Project", + nullptr, + ImGuiWindowFlags_AlwaysAutoResize)) return; - // Title - ImGui::TextUnformatted("Enter details for your new project:"); + ImGui::Text("Create New Project"); ImGui::Separator(); ImGui::Spacing(); - // Project Name field - ImGui::InputText("##proj_name", nameBuf, sizeof(nameBuf)); - ImGui::SameLine(); - ImGui::Text("Project Name"); + // Project Name (full width) + ImGui::TextUnformatted("Project Name"); + ImGui::PushItemWidth(-1); + ImGui::InputText("##proj_name", nameBuf, IM_ARRAYSIZE(nameBuf)); + ImGui::PopItemWidth(); + ImGui::Spacing(); - // Project Path field with Browse button - ImGui::PushItemWidth(-100); // make path input use remaining width - ImGui::InputText("##proj_path", pathBuf, sizeof(pathBuf)); + ImGui::TextUnformatted("Project Folder"); + ImGui::PushItemWidth(-85); + ImGui::InputText("##proj_path", pathBuf, IM_ARRAYSIZE(pathBuf)); ImGui::PopItemWidth(); ImGui::SameLine(); - if (ImGui::Button("Browse...", {80, 0})) + if (ImGui::Button("Browse...", { 80, 0 })) { - std::string chosen = CreateFileDialog(FileDialogType::Project); - if (!chosen.empty()) - strncpy(pathBuf, chosen.c_str(), sizeof(pathBuf)); + if (auto chosen = OpenFolderDialog(); !chosen.empty()) + std::strncpy(pathBuf, chosen.c_str(), sizeof(pathBuf)); } - ImGui::SameLine(); - ImGui::Text("Project Folder"); - ImGui::Spacing(); - // Compute and show the final .cproj path preview - std::filesystem::path preview = std::filesystem::path(pathBuf) / (std::string(nameBuf) + ".cproj"); - ImGui::Text("Project file will be created at:"); - ImGui::TextColored(ImVec4(0.4f, 0.7f, 1.0f, 1.0f), "%s", preview.string().c_str()); - + // Preview path – wrapped so it never overflows + auto preview = std::filesystem::path(pathBuf) / (std::string(nameBuf) + ".cproj"); + ImGui::Text("Will be created at:"); + ImGui::TextWrapped("%s", preview.string().c_str()); ImGui::Spacing(); + + // Action buttons centered ImGui::Separator(); + float btnW = 80.0f; + float totalW = btnW * 2 + ImGui::GetStyle().ItemSpacing.x; + float offsetX = (ImGui::GetWindowWidth() - totalW) * 0.5f; + ImGui::SetCursorPosX(offsetX); - // Buttons: Cancel and Create - float width = ImGui::GetContentRegionAvail().x; - ImGui::Dummy({0,0}); // for a little vertical padding - if (ImGui::Button("Cancel", {width * 0.45f, 0})) - { + if (ImGui::Button("Cancel", { btnW, 0 })) ImGui::CloseCurrentPopup(); - } + ImGui::SameLine(); - if (ImGui::Button("Create Project", {width * 0.45f, 0})) + ImGui::SetItemDefaultFocus(); + if (ImGui::Button("Create", { btnW, 0 })) { - CreateProject(nameBuf, pathBuf); + CreateProject(pathBuf, nameBuf); + nameBuf[0] = pathBuf[0] = '\0'; ImGui::CloseCurrentPopup(); - - // Clear buffers for next time - nameBuf[0] = '\0'; - pathBuf[0] = '\0'; } ImGui::EndPopup(); @@ -95,6 +91,10 @@ void ProjectManager::ShowCreateProjectPopup(bool* pOpen) + + + + bool CreateDirectories(const fs::path &baseDir) { static const std::vector subdirs = { diff --git a/src/src/core/functions/ProjectManager.h b/src/src/core/functions/ProjectManager.h index 6c21d7a..2d7eae1 100644 --- a/src/src/core/functions/ProjectManager.h +++ b/src/src/core/functions/ProjectManager.h @@ -1,9 +1,7 @@ -// ProjectManager.h #pragma once #include #include -#include class ProjectManager { @@ -25,7 +23,7 @@ public: static bool CreateProject(const std::string& projectPath, const std::string& projectName); - void ShowCreateProjectPopup(bool* pOpen); + static void ShowCreateProjectPopup(); static const std::string& GetCurrentProjectPath(); diff --git a/src/src/core/utils/FileDialog.cpp b/src/src/core/utils/FileDialog.cpp index 3d6192a..808ecf8 100644 --- a/src/src/core/utils/FileDialog.cpp +++ b/src/src/core/utils/FileDialog.cpp @@ -8,7 +8,9 @@ #include #include "FileDialog.h" #include - +#include +#include // IFileOpenDialog +#include // _com_error for error messages //TODO: Make this all memroy safe. @@ -148,3 +150,53 @@ std::vector OpenMultipleFilesDialog(FileDialogType type) { return selectedFiles; } + + + +std::string OpenFolderDialog() +{ + // Initialize COM on this thread (you can move this to your app startup instead) + CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED | COINIT_DISABLE_OLE1DDE); + + IFileOpenDialog* pDialog = nullptr; + HRESULT hr = CoCreateInstance( + CLSID_FileOpenDialog, + nullptr, + CLSCTX_INPROC_SERVER, + IID_PPV_ARGS(&pDialog) + ); + if (FAILED(hr)) + return ""; + + // Configure it as a folder picker + DWORD options = 0; + if (SUCCEEDED(pDialog->GetOptions(&options))) + pDialog->SetOptions(options | FOS_PICKFOLDERS | FOS_FORCEFILESYSTEM); + + // Show with no owner HWND + hr = pDialog->Show(nullptr); + + std::string result; + if (SUCCEEDED(hr)) + { + IShellItem* pItem = nullptr; + if (SUCCEEDED(pDialog->GetResult(&pItem))) + { + PWSTR pszPath = nullptr; + if (SUCCEEDED(pItem->GetDisplayName(SIGDN_FILESYSPATH, &pszPath))) + { + // Convert wide→narrow + std::wstring wstr(pszPath); + CoTaskMemFree(pszPath); + result.assign(wstr.begin(), wstr.end()); + } + pItem->Release(); + } + } + + pDialog->Release(); + CoUninitialize(); + return result; +} + + diff --git a/src/src/core/utils/FileDialog.h b/src/src/core/utils/FileDialog.h index eec7bf6..f0aaecb 100644 --- a/src/src/core/utils/FileDialog.h +++ b/src/src/core/utils/FileDialog.h @@ -23,6 +23,7 @@ enum class FileDialogType { std::string OpenFileDialog(FileDialogType type); std::string SaveFileDialog(FileDialogType type); std::string CreateFileDialog(FileDialogType type); +std::string OpenFolderDialog(); std::vector OpenMultipleFilesDialog(FileDialogType type);