diff --git a/CMakeLists.txt b/CMakeLists.txt index 0586614..0c82274 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -75,7 +75,6 @@ set(LUNARIUM_SRC "src/graphics/opengl/glText.cpp" "src/graphics/opengl/glShader.cpp" "src/gui/gui.cpp" -"src/gui/file_browser.cpp" "src/gui/panel.cpp" "src/gui/console.cpp" "src/internal_data/data_manager.cpp" diff --git a/docs/tasks/core.todo b/docs/tasks/core.todo index b18cf34..d581f51 100644 --- a/docs/tasks/core.todo +++ b/docs/tasks/core.todo @@ -16,7 +16,7 @@ Core: ✔ Utils @done(22-05-13 17:29) ✔ assets @done(22-05-17 14:27) ✔ gui @done(22-05-17 14:27) - ☐ Replace the File Browser (imgui) class with the NFD library (https://github.com/btzy/nativefiledialog-extended) @high + ✔ Replace the File Browser (imgui) class with the NFD library (https://github.com/btzy/nativefiledialog-extended) @high @done(22-05-23 16:00) ☐ Add log settings to the state file ✔ Refactor log system to use separate log level methods instead of passing log level @done(22-05-12 16:46) ✔ Add log level options to config script @done(22-05-12 16:46) diff --git a/docs/tasks/editor.todo b/docs/tasks/editor.todo index 5292cac..0597fa2 100644 --- a/docs/tasks/editor.todo +++ b/docs/tasks/editor.todo @@ -45,7 +45,7 @@ Editor: Tools: Tile Map Editor: - ☐ Switch to NFD dialogs (or move tile set import to the main editor) @high + ✔ Switch to NFD dialogs (or move tile set import to the main editor) @high @done(22-05-23 16:01) ☐ Allow Tile Maps to be named Tile Map Canvas: diff --git a/src/gui/file_browser.cpp b/src/gui/file_browser.cpp deleted file mode 100644 index 065986b..0000000 --- a/src/gui/file_browser.cpp +++ /dev/null @@ -1,279 +0,0 @@ -/****************************************************************************** -* File - fileBrowser.cpp -* Author - Joey Pollack -* Date - 2021/11/04 (y/m/d) -* Mod Date - 2021/11/04 (y/m/d) -* Description - File browser dialog window. Can be used for opening -* and saving files. -******************************************************************************/ - -#include "file_browser.h" - -#include -#include -#include -#include -#include -#include -#include -#include "dearimgui/imgui.h" - -namespace lunarium -{ - FileBrowser::FileBrowser() - : mIsOpen(false), mSelectionMode(SelectionMode::FILES_ONLY), mWarnOnExisting(false), mResult(Result::CANCEL) - - { - mPrompt = "Select an item"; - memset(mDirNameBuffer, 0, mBufferSize); - memset(mInputBuffer, 0, mBufferSize); - } - - /// If the given path does not exist this will default to the - /// current working directory - bool FileBrowser::OpenInDirectory(std::filesystem::path path) - { - if (mIsOpen) - return false; - - if (!std::filesystem::exists(path)) - path = std::filesystem::current_path(); - - if (!std::filesystem::is_directory(path)) - return false; - - mCurrentDirectory = path; - mResult = Result::STILL_WAITING; - - // Get list of items in the current directory - ReloadItems(); - - mIsOpen = true; - return true; - } - - bool FileBrowser::DoFrame() - { - if (!mIsOpen) - return false; - - ImGui::SetNextWindowSize(ImVec2(600, 400), ImGuiCond_Appearing); - if (!ImGui::Begin("File Browser", &mIsOpen, ImGuiWindowFlags_NoCollapse | ImGuiWindowFlags_NoDocking)) - { - ImGui::End(); - return false; - } - - ImGui::TextUnformatted(mPrompt.c_str()); - ImGui::Separator(); - - ImVec2 iconSize(DataManager::mNewFolderIcon->GetWidth(), DataManager::mNewFolderIcon->GetHeight()); - if (ImGui::ImageButton((ImTextureID) DataManager::mNewFolderIcon->GetGLTextureID64(), iconSize)) - { - ImGui::OpenPopup("New Folder Name"); - memset(mDirNameBuffer, 0, mBufferSize); - } - - if (ImGui::BeginPopup("New Folder Name")) - { - if (ImGui::InputText("Folder Name", mDirNameBuffer, mBufferSize, ImGuiInputTextFlags_EnterReturnsTrue)) - { - std::filesystem::create_directory(mDirNameBuffer); - ImGui::CloseCurrentPopup(); - ReloadItems(); - } - ImGui::EndPopup(); - } - - ImGui::SameLine(); - iconSize = ImVec2(DataManager::mUpArrowIcon->GetWidth(), DataManager::mUpArrowIcon->GetHeight()); - if (ImGui::ImageButton((ImTextureID) DataManager::mUpArrowIcon->GetGLTextureID64(), iconSize)) - { - mCurrentDirectory = mCurrentDirectory.parent_path(); - ReloadItems(); - } - - ImGui::SameLine(); - ImGui::TextUnformatted(mCurrentDirectory.string().c_str()); - - DoListBox(); - - ImGui::Separator(); - - if (ImGui::InputText("selection", mInputBuffer, mBufferSize)) - { - mInputSelection = mCurrentDirectory / mInputBuffer; - //mInputSelection = mInputBuffer; - mpSelectedItem = &mInputSelection; - } - - ImGui::Separator(); - - bool res = DoButtons(); - - ImGui::End(); - return res; - } - - void FileBrowser::AddExtensionFilter(std::string ext) - { - mExtensionsFilter.push_back(ext); - } - - void FileBrowser::SetSelectionMode(SelectionMode mode) - { - mSelectionMode = mode; - } - - void FileBrowser::WarnOnExistingFileSelection(bool warn) - { - mWarnOnExisting = warn; - } - - void FileBrowser::SetPrompt(std::string prompt) - { - mPrompt = prompt; - } - - - /// returns nullptr if the dialog has not been opened yet - const std::filesystem::path* FileBrowser::GetSelectedItem() const - { - return mpSelectedItem; - } - - FileBrowser::Result FileBrowser::GetResult() const - { - return mResult; - } - - bool FileBrowser::IsOpen() const - { - return mIsOpen; - } - - void FileBrowser::Close() - { - mIsOpen = false; - } - - void FileBrowser::ReloadItems() - { - mpSelectedItem = nullptr; - mItemsInDir.clear(); - for(auto const& dir_entry: std::filesystem::directory_iterator{mCurrentDirectory}) - { - mItemsInDir.push_back(dir_entry.path()); - } - - // Sort by type and then by name - std::sort(mItemsInDir.begin(), mItemsInDir.end(), [](std::filesystem::path& lhs, std::filesystem::path& rhs) - { - if (std::filesystem::is_directory(lhs) && std::filesystem::is_directory(rhs)) - { - return strcmp(lhs.filename().string().c_str(), rhs.filename().string().c_str()) < 0; - } - - if (std::filesystem::is_directory(lhs) && !std::filesystem::is_directory(rhs)) - { - return true; - } - - return false; - }); - } - - //////////////////////////////////////////////////////////// - // RENDER HELPER METHODS - //////////////////////////////////////////////////////////// - void FileBrowser::DoListBox() - { - if (ImGui::BeginListBox("", ImVec2(ImGui::GetWindowWidth(), ImGui::GetWindowHeight() * .575f))) - { - for (int i = 0; i < mItemsInDir.size(); i++) - { - if (std::filesystem::is_directory(mItemsInDir[i])) - { - ImVec2 size(DataManager::mFolderIcon->GetWidth(), DataManager::mFolderIcon->GetHeight()); - ImTextureID id = (ImTextureID) DataManager::mFolderIcon->GetGLTextureID64(); - ImGui::Image(id, size); - ImGui::SameLine(); - } - if (ImGui::Selectable(mItemsInDir[i].filename().string().c_str())) - { - if (std::filesystem::is_directory(mItemsInDir[i])) - { - mCurrentDirectory /= mItemsInDir[i]; - ReloadItems(); - - if (mSelectionMode == SelectionMode::DIRECTORIES_ONLY || mSelectionMode == SelectionMode::ANY) - { - mpSelectedItem = &mCurrentDirectory; - } - } - else - { - if (mSelectionMode == SelectionMode::FILES_ONLY || mSelectionMode == SelectionMode::ANY) - { - mpSelectedItem = &mItemsInDir[i]; - memset(mInputBuffer, 0, mBufferSize); - memcpy(mInputBuffer, mpSelectedItem->filename().string().c_str(), mpSelectedItem->filename().string().size()); - } - } - } - } - - ImGui::EndListBox(); - } - } - - bool FileBrowser::DoButtons() - { - ImGui::SetCursorPosX(ImGui::GetWindowSize().x - 100.0f); - if (mpSelectedItem && ImGui::Button("OK")) - { - if (std::filesystem::exists(*mpSelectedItem) && mWarnOnExisting) - { - ImGui::OpenPopup("Warn"); - } - else - { - mResult = Result::OK; - mIsOpen = false; - return false; - } - } - - if (ImGui::BeginPopup("Warn")) - { - ImGui::Text("This file already exists. Are you sure you want to overwrite it?"); - if (ImGui::Button("Yes")) - { - mResult = Result::OK; - mIsOpen = false; - ImGui::EndPopup(); - return false; - } - - ImGui::SameLine(); - if (ImGui::Button("No")) - { - ImGui::CloseCurrentPopup(); - } - - ImGui::EndPopup(); - } - - ImGui::SameLine(); - - if (ImGui::Button("Cancel")) - { - mResult = Result::CANCEL; - mIsOpen = false; - return false; - } - - return true; - } -} - diff --git a/src/gui/file_browser.h b/src/gui/file_browser.h deleted file mode 100644 index 3a92977..0000000 --- a/src/gui/file_browser.h +++ /dev/null @@ -1,84 +0,0 @@ -/****************************************************************************** -* File - fileBrowser.h -* Author - Joey Pollack -* Date - 2021/11/04 (y/m/d) -* Mod Date - 2021/11/04 (y/m/d) -* Description - File browser dialog window. Can be used for opening -* and saving files. -******************************************************************************/ - -// Some useful links: -// https://en.cppreference.com/w/cpp/filesystem/is_directory -// https://en.cppreference.com/w/cpp/filesystem/path - -#ifndef FILE_SELECT_H_ -#define FILE_SELECT_H_ - -#include - -#include -#include - -namespace lunarium -{ - class Image; - class FileBrowser - { - public: - enum Result - { - OK, - CANCEL, - STILL_WAITING // TODO: Implement STILL_WAITING - }; - - enum SelectionMode - { - FILES_ONLY, - DIRECTORIES_ONLY, - ANY, - }; - - public: - - FileBrowser(); - bool OpenInDirectory(std::filesystem::path path); - bool DoFrame(); - bool IsOpen() const; - void Close(); - - void SetPrompt(std::string prompt); - void AddExtensionFilter(std::string ext); - void SetSelectionMode(SelectionMode mode); - void WarnOnExistingFileSelection(bool warn); - - // returns nullptr if the dialog has not been opened yet - const std::filesystem::path* GetSelectedItem() const; - Result GetResult() const; - - private: - - bool mIsOpen; - SelectionMode mSelectionMode; - bool mWarnOnExisting; - Result mResult; - std::string mPrompt; - std::filesystem::path mCurrentDirectory; - std::vector mItemsInDir; - std::vector mExtensionsFilter; // Show only these extensions. If empty show all files. - std::filesystem::path* mpSelectedItem; - std::filesystem::path mInputSelection; - - static const int mBufferSize = 256; - char mDirNameBuffer[mBufferSize]; - char mInputBuffer[mBufferSize]; - - private: - void ReloadItems(); - void DoListBox(); - bool DoButtons(); - }; -} - - -#endif // FILE_SELECT_H_ \ No newline at end of file diff --git a/src/run_modes/editor/contents/content_manager.cpp b/src/run_modes/editor/contents/content_manager.cpp index 8f21f84..b9bff65 100644 --- a/src/run_modes/editor/contents/content_manager.cpp +++ b/src/run_modes/editor/contents/content_manager.cpp @@ -58,18 +58,6 @@ namespace lunarium { namespace editor // If this is a new project being generated just create a base contents file if (!std::filesystem::exists(mContentFile)) { - // pugi::xml_node proj_node = doc.append_child("Project"); - // proj_node.append_attribute("Name").set_value(mpProject->GetName().c_str()); - - // mNextID = 0; - // proj_node.append_child("NextID").append_attribute("ID").set_value(mNextID); - // // pugi::xml_node proj_node = doc.append_child("Contents"); - // proj_node.append_child("Contents"); - // if (!doc.save_file(mContentFile.string().c_str())) - // { - // return OpRes::Fail("ContentManager could not save file: %s", mContentFile.string().c_str()); - // } - return Save(); } @@ -106,25 +94,6 @@ namespace lunarium { namespace editor // Not actually an error if a project does not have any content yet //return OpRes::Fail("content_meta.xml missing Contents node"); } - - // ARRAY EXAMPLE - /* - std::string raw = "{\"Contents\" : [ { \"Name\" : \"first\", \"ID\" : 1 }, { \"Name\" : \"second\", \"ID\" : 2 }]}"; - - auto j = nlohmann::json::parse(raw); - - for (auto it = j["Contents"].begin(); it != j["Contents"].end(); ++it) - { - std::cout << (*it)["ID"] << " - " << (*it)["Name"] << "\n"; - } - - nlohmann::json oj; - oj["Contents"].push_back({ {"Name", "first"}, {"ID", 1} }); - oj["Contents"].push_back({ {"Name", "second"}, { "ID", 2 } }); - - std::cout << "\n" << std::setw(4) << oj; - */ - /////////////////////////////////// for (auto it = c.begin(); it != c.end(); ++it) { diff --git a/src/run_modes/editor/tools/map_editor/map_editor.cpp b/src/run_modes/editor/tools/map_editor/map_editor.cpp index 1a07be2..f859020 100644 --- a/src/run_modes/editor/tools/map_editor/map_editor.cpp +++ b/src/run_modes/editor/tools/map_editor/map_editor.cpp @@ -17,6 +17,7 @@ #include #include #include +#include // Panels #include "panels/map_canvas.h" @@ -110,11 +111,6 @@ namespace lunarium { namespace editor ImGui::End(); mPanelManager.RenderPanels(); - - if (mFileBrowser.IsOpen()) - { - mFileBrowser.DoFrame(); - } return true; } @@ -221,14 +217,40 @@ namespace lunarium { namespace editor ImGui::Separator(); if (ImGui::MenuItem("Import Tile Set")) { - mImportTileSet = true; - mFileBrowser.SetSelectionMode(FileBrowser::SelectionMode::FILES_ONLY); - mFileBrowser.SetPrompt("Find the tile set image"); - if (!mFileBrowser.OpenInDirectory("")) + NFD::Guard nfdGuard; + + // auto-freeing memory + NFD::UniquePath outPath; + + // prepare filters for the dialog + nfdfilteritem_t filterItem[3] = {{"Image file", "png"}, {"Image File", "jpg"}, {"Image File", "jpeg"}}; + + // show the dialog + nfdresult_t result = NFD::OpenDialog(outPath, filterItem, 3); + if (result == NFD_OKAY) { - mImportTileSet = false; - Logger::Error(Editor::LogCat, "Could not open the File Browser"); + std::filesystem::path the_path = outPath.get(); + + Logger::Info(Editor::LogCat, "Importing asset: %s", the_path.string().c_str()); + + uint64_t id = 0; + ContentManager::GetInstance().ImportFile(the_path, mpEditor->GetAssetBrowserLocation() / the_path.filename(), AssetType::EATYPE_TILE_SET, id).LogIfFailed(Editor::LogCat); + + TileSet* ts = (TileSet*)ContentManager::GetInstance().GetAsset(id); + ts->SetTileSize({16, 16}); // NOTE: Hardcoding the tile size for testing + ts->SetTileSetID(mTileSetNextID); + mTileSets[mTileSetNextID] = ts; + mTileSetNextID++; + + // Check if the tile set can be used on the current map + if (mpMap && mpMap->GetTileSize() == ts->GetTileSize()) + { + mpMap->AddTileSet(ts->GetTileSetID(), ts); + ((TileSetView*)mPanelManager.GetPanel(mPanels.TileSetView))->AddTileSet(ts); + } + } + } ImGui::Separator(); @@ -262,38 +284,6 @@ namespace lunarium { namespace editor void MapEditor::HandleMenuEvents() { - if (mImportTileSet) - { - if (mFileBrowser.GetResult() == FileBrowser::Result::OK) - { - auto path = mFileBrowser.GetSelectedItem(); - Logger::Info(Editor::LogCat, "Importing tile set: %s", path->string().c_str()); - - uint64_t id = 0; - ContentManager::GetInstance().ImportFile(*path, mpEditor->GetAssetBrowserLocation() / path->filename(), AssetType::EATYPE_TILE_SET, id).LogIfFailed(Editor::LogCat); - - TileSet* ts = (TileSet*)ContentManager::GetInstance().GetAsset(id); - ts->SetTileSize({16, 16}); // NOTE: Hardcoding the tile size for testing - ts->SetTileSetID(mTileSetNextID); - mTileSets[mTileSetNextID] = ts; - mTileSetNextID++; - - // Check if the tile set can be used on the current map - if (mpMap && mpMap->GetTileSize() == ts->GetTileSize()) - { - mpMap->AddTileSet(ts->GetTileSetID(), ts); - ((TileSetView*)mPanelManager.GetPanel(mPanels.TileSetView))->AddTileSet(ts); - } - - mImportTileSet = false; - } - else if (mFileBrowser.GetResult() == FileBrowser::Result::CANCEL) - { - Logger::Info(Editor::LogCat, "New Project operation cancelled"); - mImportTileSet = false; - } - - } } diff --git a/src/run_modes/editor/tools/map_editor/map_editor.h b/src/run_modes/editor/tools/map_editor/map_editor.h index 7fd01f2..27dffeb 100644 --- a/src/run_modes/editor/tools/map_editor/map_editor.h +++ b/src/run_modes/editor/tools/map_editor/map_editor.h @@ -14,7 +14,6 @@ #include #include #include "../../panel_manager.h" -#include #include namespace lunarium { @@ -66,8 +65,6 @@ namespace editor uint32_t TileSetView; } mPanels; - FileBrowser mFileBrowser; - int mTileSetNextID; std::map mTileSets;