diff --git a/Editor/src/Misc/PopupHelper.cpp b/Editor/src/Misc/PopupHelper.cpp index 6159234a..a0346ebc 100644 --- a/Editor/src/Misc/PopupHelper.cpp +++ b/Editor/src/Misc/PopupHelper.cpp @@ -1,15 +1,15 @@ #include "PopupHelper.h" #include "imgui/imgui.h" +#include "regex" - -void PopupHelper::Confirmation(const std::string& id) +void PopupHelper::OpenPopup(const std::string& id) { ImGui::TextWrapped(id.c_str()); ImGui::OpenPopup(id.c_str()); } -bool PopupHelper::DefineDialog(const std::string& id, const std::string& text) +bool PopupHelper::DefineConfirmationDialog(const std::string& id, const std::string& text) { bool result = false; @@ -30,3 +30,56 @@ bool PopupHelper::DefineDialog(const std::string& id, const std::string& text) return result; } + +bool PopupHelper::DefineTextDialog(const std::string& id, std::string& currentText) +{ + bool result = false; + + ImVec2 center = ImGui::GetMainViewport()->GetCenter(); + ImGui::SetNextWindowPos(center, ImGuiCond_Appearing, ImVec2(0.5f, 0.5f)); + + if (ImGui::BeginPopupModal(id.c_str(), NULL, ImGuiWindowFlags_AlwaysAutoResize)) + { + bool isSanitized = true; + + char buffer[256]; + memset(buffer, 0, sizeof(buffer)); + std::strncpy(buffer, currentText.c_str(), sizeof(buffer)); + if (ImGui::InputText("", buffer, sizeof(buffer))) + { + currentText = std::string(buffer); + } + + // returns false when there is a match, quirky + if (!regex_match(buffer, std::regex("[^ \\ / :*? \"<>|]+"))) + { + isSanitized = false; + } + + if (currentText.empty()) + { + ImGui::TextColored(ImVec4(0.76, 0.45, 0.47, 1.0), "A file name can't be empty."); + } + else if (!isSanitized) + { + ImGui::TextColored(ImVec4(0.76, 0.45, 0.47, 1.0), "A file name can't contain any of the following characters: \\/:*?\"<>|"); + } + + ImGui::Separator(); + + if (ImGui::Button("OK", ImVec2(120, 0))) + { + if (isSanitized) + { + result = true; + ImGui::CloseCurrentPopup(); + } + } + ImGui::SetItemDefaultFocus(); + ImGui::SameLine(); + if (ImGui::Button("Cancel", ImVec2(120, 0))) { ImGui::CloseCurrentPopup(); } + ImGui::EndPopup(); + } + + return result; +} diff --git a/Editor/src/Misc/PopupHelper.h b/Editor/src/Misc/PopupHelper.h index 74304103..7e9c27d8 100644 --- a/Editor/src/Misc/PopupHelper.h +++ b/Editor/src/Misc/PopupHelper.h @@ -4,6 +4,7 @@ class PopupHelper { public: - static void Confirmation(const std::string& id); - static bool DefineDialog(const std::string& id, const std::string& text); + static void OpenPopup(const std::string& id); + static bool DefineConfirmationDialog(const std::string& id, const std::string& text); + static bool PopupHelper::DefineTextDialog(const std::string& id, std::string& currentText); }; diff --git a/Editor/src/Windows/FileSystemUI.cpp b/Editor/src/Windows/FileSystemUI.cpp index 97dcfd47..0f99b818 100644 --- a/Editor/src/Windows/FileSystemUI.cpp +++ b/Editor/src/Windows/FileSystemUI.cpp @@ -31,6 +31,9 @@ namespace Nuake { } + + std::string renameTempValue = ""; + void FileSystemUI::EditorInterfaceDrawFiletree(Ref dir) { ImGuiTreeNodeFlags base_flags = ImGuiTreeNodeFlags_OpenOnArrow | ImGuiTreeNodeFlags_OpenOnDoubleClick | ImGuiTreeNodeFlags_SpanFullWidth | ImGuiTreeNodeFlags_FramePadding; @@ -73,6 +76,9 @@ namespace Nuake m_hasClickedOnFile = true; } + const std::string rename = "Rename" + std::string("##") + hoverMenuId; + bool shouldRename = false; + if (ImGui::BeginPopup(hoverMenuId.c_str())) { if (ImGui::MenuItem("Open")) @@ -106,12 +112,10 @@ namespace Nuake RefreshFileBrowser(); } - ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1, 1, 1, 0.2f)); if (ImGui::MenuItem("Rename")) { - + shouldRename = true; } - ImGui::PopStyleColor(); ImGui::Separator(); @@ -123,6 +127,22 @@ namespace Nuake ImGui::EndPopup(); } + if (shouldRename) + { + renameTempValue = directory->name; + PopupHelper::OpenPopup(rename); + } + + if (PopupHelper::DefineTextDialog(rename, renameTempValue)) + { + if (OS::RenameDirectory(directory, renameTempValue) != 0) + { + Logger::Log("Cannot rename directory: " + renameTempValue, "editor", CRITICAL); + } + RefreshFileBrowser(); + renameTempValue = ""; + } + ImGui::Text(directory->name.c_str()); ImGui::PopFont(); } @@ -206,6 +226,8 @@ namespace Nuake const std::string openScene = "Open Scene" + std::string("##") + hoverMenuId; bool shouldOpenScene = false; + const std::string rename = "Rename" + std::string("##") + hoverMenuId; + bool shouldRename = false; if (ImGui::BeginPopup(hoverMenuId.c_str())) { @@ -268,12 +290,10 @@ namespace Nuake } } - ImGui::PushStyleColor(ImGuiCol_Text, ImVec4(1, 1, 1, 0.2f)); if (ImGui::MenuItem("Rename")) { - + shouldRename = true; } - ImGui::PopStyleColor(); ImGui::Separator(); @@ -290,12 +310,14 @@ namespace Nuake shouldOpenScene = file->GetExtension() == ".scene"; } + // Open Scene Popup + if (shouldOpenScene) { - PopupHelper::Confirmation(openScene); + PopupHelper::OpenPopup(openScene); } - if (PopupHelper::DefineDialog(openScene, " Open the scene? \n Changes will not be saved.")) + if (PopupHelper::DefineConfirmationDialog(openScene, " Open the scene? \n Changes will not be saved.")) { Ref scene = Scene::New(); const std::string projectPath = file->GetAbsolutePath(); @@ -309,6 +331,25 @@ namespace Nuake Engine::LoadScene(scene); } + // Rename Popup + + if (shouldRename) + { + renameTempValue = file->GetName(); + PopupHelper::OpenPopup(rename); + } + + if (PopupHelper::DefineTextDialog(rename, renameTempValue)) + { + if(OS::RenameFile(file, renameTempValue) != 0) + { + Logger::Log("Cannot rename file: " + renameTempValue, "editor", CRITICAL); + } + RefreshFileBrowser(); + renameTempValue = ""; + } + + ImGui::Text(file->GetName().c_str()); ImGui::PopFont(); } diff --git a/Nuake/src/Core/OS.cpp b/Nuake/src/Core/OS.cpp index c2fd29bf..eb9bc215 100644 --- a/Nuake/src/Core/OS.cpp +++ b/Nuake/src/Core/OS.cpp @@ -7,6 +7,7 @@ #include #include +#include using namespace Nuake; @@ -44,6 +45,25 @@ void OS::OpenIn(const std::string& filePath) ShellExecuteA(nullptr, "open", filePath.c_str(), nullptr, nullptr, SW_SHOWDEFAULT); } +int OS::RenameFile(const Ref& file, const std::string& newName) +{ + std::string extension = !String::EndsWith(newName, file->GetExtension().c_str()) ? file->GetExtension() : ""; + std::string newFilePath = file->GetParent()->fullPath + newName + extension; + + std::error_code resultError; + std::filesystem::rename(file->GetAbsolutePath().c_str(), newFilePath.c_str(), resultError); + return resultError.value() == 0; +} + +int OS::RenameDirectory(const Ref& dir, const std::string& newName) +{ + std::string newDirPath = dir->Parent->fullPath + newName; + + std::error_code resultError; + std::filesystem::rename(dir->fullPath.c_str(), newDirPath.c_str(), resultError); + return resultError.value() == 0; +} + void OS::ShowInFileExplorer(const std::string& filePath) { ShellExecuteA(nullptr, "open", "explorer.exe", ("/select," + std::string(filePath)).c_str(), nullptr, SW_SHOWDEFAULT); diff --git a/Nuake/src/Core/OS.h b/Nuake/src/Core/OS.h index 657b1fb5..c1b5b8e3 100644 --- a/Nuake/src/Core/OS.h +++ b/Nuake/src/Core/OS.h @@ -1,6 +1,7 @@ #pragma once #include +#include "FileSystem.h" namespace Nuake { @@ -11,6 +12,8 @@ namespace Nuake static std::string GetFromClipboard(); static int GetTime(); static void OpenIn(const std::string& filePath); + static int OS::RenameFile(const Ref& file, const std::string& newName); + static int OS::RenameDirectory(const Ref& dir, const std::string& newName); static void ShowInFileExplorer(const std::string& filePath); }; }