fixes project creation and loading
fixes asset importing
gui_api_redesign
Joey Pollack 4 years ago
parent 6f00e84229
commit 016809cc3f

3
.gitignore vendored

@ -64,3 +64,6 @@ build/
######################## ASSET IGNORES ######################## ASSET IGNORES
ui_files/ ui_files/
######################## TEST FILE IGNORES
test*/

3
.gitmodules vendored

@ -13,3 +13,6 @@
[submodule "external/box2d"] [submodule "external/box2d"]
path = external/box2d path = external/box2d
url = https://github.com/erincatto/box2d url = https://github.com/erincatto/box2d
[submodule "external/nativefiledialog-extended"]
path = external/nativefiledialog-extended
url = https://github.com/btzy/nativefiledialog-extended.git

@ -151,6 +151,9 @@ add_subdirectory(external/freetype)
# add box2d # add box2d
add_subdirectory(external/box2d) add_subdirectory(external/box2d)
# add nativefiledialog
add_subdirectory(external/nativefiledialog-extended)
# add run mode tester # add run mode tester
add_subdirectory(src/run_modes/testbed) add_subdirectory(src/run_modes/testbed)
@ -173,6 +176,7 @@ target_include_directories(${PROJECT_NAME}
PUBLIC external/glad/include PUBLIC external/glad/include
PUBLIC external/freetype/include PUBLIC external/freetype/include
PUBLIC external/box2d/include PUBLIC external/box2d/include
PUBLIC external/nativefiledialog-extended/src/include
) )
target_link_directories(${PROJECT_NAME} target_link_directories(${PROJECT_NAME}
@ -183,9 +187,10 @@ target_link_directories(${PROJECT_NAME}
PRIVATE external/glad/src PRIVATE external/glad/src
PRIVATE external/freetype/src PRIVATE external/freetype/src
PRIVATE external/box2d/bin PRIVATE external/box2d/bin
PRIVATE external/nativefiledialog-extended
) )
target_link_libraries(${PROJECT_NAME} box2d glfw glad glm dearimgui lua_static freetype testbed) target_link_libraries(${PROJECT_NAME} box2d glfw glad glm dearimgui lua_static freetype nfd testbed)
if (NOT NO_EDITOR) if (NOT NO_EDITOR)
target_link_libraries(${PROJECT_NAME} editor) target_link_libraries(${PROJECT_NAME} editor)

@ -1,6 +1,6 @@
High Importance: High Importance:
Editor does not get absolute paths from the file browser - replace with NFD dialogs @critical Editor does not get absolute paths from the file browser - replace with NFD dialogs @critical @done(22-05-20 18:36)
✔ The Map Editor does not get the tile maps when a project is opened @high @done (3/3/2022, 2:47:41 PM) ✔ The Map Editor does not get the tile maps when a project is opened @high @done (3/3/2022, 2:47:41 PM)
✔ Tile Set IDs (as opposed to the Asset ID) is not saved or loaded yet @high @done (3/11/2022, 2:10:30 PM) ✔ Tile Set IDs (as opposed to the Asset ID) is not saved or loaded yet @high @done (3/11/2022, 2:10:30 PM)
✔ Had to flip the V component of the UVs for the sprite vertices. This fixes the partial image drawing but will need to be accounted for in other places in the editor. @done (3/14/2022, 1:46:48 PM) ✔ Had to flip the V component of the UVs for the sprite vertices. This fixes the partial image drawing but will need to be accounted for in other places in the editor. @done (3/14/2022, 1:46:48 PM)

@ -7,7 +7,8 @@ Build System:
✔ Modify .sh scripts to recognize the noeditor flag @done (1/25/2022, 3:59:23 PM) ✔ Modify .sh scripts to recognize the noeditor flag @done (1/25/2022, 3:59:23 PM)
Core: Core:
Add custom (64 bit?) UUID generator (based on Chreno's UUIDs: ) ☐ Wrap NFD in an API in the platform module @low
☐ Add custom (64 bit?) UUID generator (based on Chreno's UUIDs)
✔ Add Terminal subsystem to allow for printing colored text in a cross-platform way @done(22-05-16 18:05) ✔ Add Terminal subsystem to allow for printing colored text in a cross-platform way @done(22-05-16 18:05)
✔ Create a LogListener that uses the colored text (replace the current stdout listener) @done(22-05-16 18:23) ✔ Create a LogListener that uses the colored text (replace the current stdout listener) @done(22-05-16 18:23)
✔ Replace XML with JSON (https://github.com/nlohmann/json) @high @done(22-05-19 15:35) ✔ Replace XML with JSON (https://github.com/nlohmann/json) @high @done(22-05-19 15:35)

@ -1,7 +1,7 @@
Editor: Editor:
Asset Location MUST be relative to the project root directory @critical Asset Location MUST be relative to the project root directory @critical @done(22-05-20 18:35)
☐ Switch to NFD dialogs ✔ Switch to NFD dialogs @done(22-05-20 18:35)
✔ Come up with project directory structure @done (9/17/2021, 6:46:44 PM) ✔ Come up with project directory structure @done (9/17/2021, 6:46:44 PM)
✔ Make the editor a separate module @high @done (11/1/2021, 2:24:35 PM) ✔ Make the editor a separate module @high @done (11/1/2021, 2:24:35 PM)
✔ Implement Run Mode interface class @high @done (2/8/2022, 4:05:17 PM) ✔ Implement Run Mode interface class @high @done (2/8/2022, 4:05:17 PM)
@ -45,6 +45,7 @@ Editor:
Tools: Tools:
Tile Map Editor: Tile Map Editor:
☐ Switch to NFD dialogs (or move tile set import to the main editor) @high
☐ Allow Tile Maps to be named ☐ Allow Tile Maps to be named
Tile Map Canvas: Tile Map Canvas:

@ -0,0 +1 @@
Subproject commit 28ade5a5cc5d17cea8fe4034572cac8fd54eb53f

@ -21,12 +21,16 @@ set(EDITOR_SRC
add_library(editor ${EDITOR_SRC}) add_library(editor ${EDITOR_SRC})
target_link_libraries(editor) target_link_directories(editor
PRIVATE ${PROJECT_BINARY_DIR}/external/nativefiledialog-extended)
target_link_libraries(editor nfd)
target_include_directories(editor target_include_directories(editor
PUBLIC "${PROJECT_BINARY_DIR}" PUBLIC "${PROJECT_BINARY_DIR}"
PUBLIC ../../ PUBLIC ../../
PUBLIC ../../run_modes PUBLIC ../../run_modes
PUBLIC external/nativefiledialog-extended/src/include
PUBLIC ../../../external/glm PUBLIC ../../../external/glm
PUBLIC ../../../external/glad/include PUBLIC ../../../external/glad/include
PUBLIC ../../../external/glfw/include PUBLIC ../../../external/glfw/include

@ -101,7 +101,10 @@ namespace lunarium { namespace editor
if (c.is_null()) if (c.is_null())
{ {
return OpRes::Fail("content_meta.xml missing Contents node"); return OpRes::OK();
// Not actually an error if a project does not have any content yet
//return OpRes::Fail("content_meta.xml missing Contents node");
} }
// ARRAY EXAMPLE // ARRAY EXAMPLE
@ -176,7 +179,7 @@ namespace lunarium { namespace editor
return OpRes::Fail("ConentManager::Save failed: no project set"); return OpRes::Fail("ConentManager::Save failed: no project set");
} }
nlohmann::json oj; nlohmann::ordered_json oj;
auto& p = oj["Project"]; auto& p = oj["Project"];
// Save header info // Save header info
@ -204,7 +207,7 @@ namespace lunarium { namespace editor
c.push_back(asset); c.push_back(asset);
} }
std::ofstream ofs = std::ofstream(mContentFile.string().c_str()); std::ofstream ofs = std::ofstream(mContentFile.string().c_str(), std::ios_base::trunc);
if (!ofs.is_open()) if (!ofs.is_open())
{ {
return OpRes::Fail("ContentManager could not save file: %s - could not open file", mContentFile.string().c_str()); return OpRes::Fail("ContentManager could not save file: %s - could not open file", mContentFile.string().c_str());
@ -279,6 +282,11 @@ namespace lunarium { namespace editor
return OpRes::Fail("Could not import asset, ID collision. ID: %llu", mNextID); return OpRes::Fail("Could not import asset, ID collision. ID: %llu", mNextID);
} }
if (std::filesystem::exists(to_location))
{
std::filesystem::remove(to_location);
}
if (!std::filesystem::copy_file(file, to_location)) if (!std::filesystem::copy_file(file, to_location))
{ {
return OpRes::Fail("Could not copy asset file from: %s to: %s", file.string().c_str(), to_location.string().c_str()); return OpRes::Fail("Could not copy asset file from: %s to: %s", file.string().c_str(), to_location.string().c_str());
@ -290,7 +298,7 @@ namespace lunarium { namespace editor
pAsset->mAssetDir = mpProject->GetAssetDirectory(); pAsset->mAssetDir = mpProject->GetAssetDirectory();
pAsset->mID = mNextID; pAsset->mID = mNextID;
mNextID++; mNextID++;
pAsset->mLocation = mpProject->MakeRelativeToRoot(to_location); pAsset->mLocation = mpProject->MakeRelativeToAssets(to_location);
if (Failed(pAsset->LoadRawFile().LogIfFailed(Editor::LogCat))) if (Failed(pAsset->LoadRawFile().LogIfFailed(Editor::LogCat)))
{ {
delete pAsset; delete pAsset;

@ -25,6 +25,8 @@
// Tools // Tools
#include "tools/map_editor/map_editor.h" #include "tools/map_editor/map_editor.h"
#include <nfd.hpp>
using namespace lunarium::gui; using namespace lunarium::gui;
// ERROR LOG MACRO // ERROR LOG MACRO
@ -37,7 +39,7 @@ namespace editor
uint32_t Editor::LogCat = -1; uint32_t Editor::LogCat = -1;
Editor::Editor() Editor::Editor()
: mpPath(nullptr), mDoNewProject(false), mDoOpenProject(false), : mDoNewProject(false), mDoOpenProject(false),
mDoSaveProject(false), mDoSaveAs(false), mNextWindowID(0), mpMapEditor(nullptr) mDoSaveProject(false), mDoSaveAs(false), mNextWindowID(0), mpMapEditor(nullptr)
{ {
} }
@ -109,11 +111,6 @@ namespace editor
{ {
mAboutPanel.DoFrame(); mAboutPanel.DoFrame();
} }
if (mFileBrowser.IsOpen())
{
mFileBrowser.DoFrame();
}
} }
uint32_t Editor::GetLogCat() const uint32_t Editor::GetLogCat() const
@ -192,122 +189,101 @@ namespace editor
void Editor::HandleMenuEvents() void Editor::HandleMenuEvents()
{ {
/////////////////////////// }
// FILE
if (mDoNewProject) ////////////////////////////////////////////////////////////
{ // MENU BAR
if (mFileBrowser.GetResult() == FileBrowser::Result::OK) ////////////////////////////////////////////////////////////
void Editor::DoMainMenu()
{ {
mpPath = mFileBrowser.GetSelectedItem(); ImGui::BeginMainMenuBar();
Logger::Info(LogCat, "Generating new project at %s", mpPath->string().c_str());
// Generate new project at mpPath // File
OpRes result = mProject.GenerateProject(mpPath->filename().string(), mpPath->parent_path()); if (ImGui::BeginMenu("File"))
if (Failed(result))
{ {
Logger::Error(LogCat, "Could not create a new project: %s", result.Description); if (ImGui::MenuItem("New Project"))
}
((AssetBrowser*)mPanelManager.GetPanel(mPanels.AssetBrowser))->SetAssetDirectory(*mpPath / std::filesystem::path("contents/assets"));
mDoNewProject = false;
}
else if (mFileBrowser.GetResult() == FileBrowser::Result::CANCEL)
{ {
Logger::Info(LogCat, "New Project operation cancelled"); NFD::Guard nfdGuard;
mDoNewProject = false;
}
} // auto-freeing memory
NFD::UniquePath outPath;
if (mDoOpenProject) // prepare filters for the dialog
{ nfdfilteritem_t filterItem[1] = {{"Lunarium Project File", "lproj"}};
if (mFileBrowser.GetResult() == FileBrowser::Result::OK)
{
mpPath = mFileBrowser.GetSelectedItem();
Logger::Info(LogCat, "Opening project: %s", mpPath->string().c_str());
// Open project at mpPath // show the dialog
if (Failed(mProject.LoadProject(*mpPath).LogIfFailed(Editor::LogCat))) nfdresult_t result = NFD::SaveDialog(outPath, filterItem, 1);
if (result == NFD_OKAY)
{ {
mDoOpenProject = false; std::filesystem::path the_path = outPath.get();
return; Logger::Info(LogCat, "Generating new project at %s", the_path.string().c_str());
} OpRes result = mProject.GenerateProject(the_path.filename().string(), the_path.parent_path());
((AssetBrowser*)mPanelManager.GetPanel(mPanels.AssetBrowser))->SetAssetDirectory(mpPath->parent_path() / std::filesystem::path("contents/assets")); if (Failed(result))
mDoOpenProject = false; {
Logger::Error(LogCat, "Could not create a new project: %s", result.Description);
} }
else if (mFileBrowser.GetResult() == FileBrowser::Result::CANCEL) else
{ {
Logger::Info(LogCat, "Open Project operation cancelled"); ((AssetBrowser*)mPanelManager.GetPanel(mPanels.AssetBrowser))->
mDoOpenProject = false; SetAssetDirectory(the_path.parent_path() / std::filesystem::path("contents/assets"));
} }
} }
else if (result == NFD_CANCEL)
if (mDoSaveProject)
{
if (!mProject.IsLoaded())
{ {
mDoSaveAs = true; Logger::Info(LogCat, "User cancelled project create");
mDoSaveProject = false;
} }
else else
{ {
mProject.SaveProject(); Logger::Error(LogCat, "Error getting project file location: %s", NFD::GetError());
mDoSaveProject = false;
} }
} }
if (mDoSaveAs) if (ImGui::MenuItem("Open Project"))
{ {
NFD::Guard nfdGuard;
mDoSaveAs = false; // auto-freeing memory
} NFD::UniquePath outPath;
///////////////////////////
} // prepare filters for the dialog
nfdfilteritem_t filterItem[1] = {{"Lunarium Project File", "lproj"}};
//////////////////////////////////////////////////////////// // show the dialog
// MENU BAR nfdresult_t result = NFD::OpenDialog(outPath, filterItem, 1);
//////////////////////////////////////////////////////////// if (result == NFD_OKAY)
void Editor::DoMainMenu()
{ {
ImGui::BeginMainMenuBar(); std::filesystem::path the_path = outPath.get();
// File Logger::Info(LogCat, "Opening project: %s", the_path.string().c_str());
if (ImGui::BeginMenu("File"))
{ // Open project at mpPath
if (ImGui::MenuItem("New Project")) if (Failed(mProject.LoadProject(the_path).LogIfFailed(Editor::LogCat)))
{ {
mDoNewProject = true; Logger::Error(LogCat, "Failed to load project: %s", the_path.string().c_str());
mFileBrowser.SetSelectionMode(FileBrowser::SelectionMode::FILES_ONLY); }
mFileBrowser.SetPrompt("Pick a location and name for the project"); else
if (!mFileBrowser.OpenInDirectory(""))
{ {
mDoNewProject = false; ((AssetBrowser*)mPanelManager.GetPanel(mPanels.AssetBrowser))->
Logger::Error(LogCat, "Could not open the File Browser"); SetAssetDirectory(the_path.parent_path() / std::filesystem::path("contents/assets"));
} }
}
if (ImGui::MenuItem("Open Project")) }
else if (result == NFD_CANCEL)
{ {
mDoOpenProject = true; Logger::Info(LogCat, "User cancelled project open");
mFileBrowser.SetSelectionMode(FileBrowser::SelectionMode::FILES_ONLY); }
mFileBrowser.SetPrompt("Pick a location and name for the project"); else
if (!mFileBrowser.OpenInDirectory(""))
{ {
mDoOpenProject = false; Logger::Error(LogCat, "Error getting project file location: %s", NFD::GetError());
Logger::Error(LogCat, "Could not open the File Browser");
} }
} }
if (ImGui::MenuItem("Save Project")) if (ImGui::MenuItem("Save Project"))
{ {
mDoSaveProject = true; mProject.SaveProject();
}
if (ImGui::MenuItem("Save Project As"))
{
mDoSaveAs = true;
} }
ImGui::Separator(); ImGui::Separator();

@ -15,7 +15,6 @@
#include "project.h" #include "project.h"
#include "panel_manager.h" #include "panel_manager.h"
#include "panels/about.h" #include "panels/about.h"
#include <gui/file_browser.h>
#include <filesystem> #include <filesystem>
#include <map> #include <map>
@ -67,9 +66,6 @@ namespace lunarium { namespace editor
unsigned int mNextWindowID; unsigned int mNextWindowID;
MapEditor* mpMapEditor; MapEditor* mpMapEditor;
FileBrowser mFileBrowser;
const std::filesystem::path* mpPath;
// Panels // Panels
struct struct
{ {

@ -30,17 +30,21 @@ namespace lunarium { namespace editor
mName = name; mName = name;
mLocation = location; mLocation = location;
mLocation /= mName; mLocation /= std::filesystem::path(mName).stem();
if (std::filesystem::exists(mLocation)) if (!std::filesystem::exists(mLocation))
{
std::filesystem::create_directory(mLocation);
}
if (std::filesystem::exists(mLocation / mName))
{ {
return OpRes::Fail("A project with that name (%s) already exists in this location: %s", mName.c_str(), mLocation.string().c_str()); return OpRes::Fail("A project with that name (%s) already exists in this location: %s", mName.c_str(), mLocation.string().c_str());
} }
std::filesystem::create_directory(mLocation);
std::filesystem::path proj_doc = mLocation; std::filesystem::path proj_doc = mLocation;
proj_doc /= std::filesystem::path(mName + ".lproj"); proj_doc /= std::filesystem::path(mName);
nlohmann::json j; nlohmann::json j;
auto& p = j["Project"]; auto& p = j["Project"];
@ -125,33 +129,24 @@ namespace lunarium { namespace editor
return GetContentDirectory() / "assets"; return GetContentDirectory() / "assets";
} }
std::filesystem::path Project::MakeRelativeToRoot(std::filesystem::path abs_path) const std::filesystem::path Project::MakeRelativeToRoot(std::filesystem::path abs_path, bool include_root) const
{ {
/* // HOW TO GET THE PATH RELATIVE TO THE PROJECT ROOT return MakeRelativeTo(abs_path, mLocation, include_root);
std::filesystem::path p = "D:\\Projects\\lunarium\\test2\\contents\\assets\\LinkToThePast1_sized.png"; }
std::cout << "\nFull Path: " << p;
std::cout << "\nRelative path: " << p.relative_path();
std::filesystem::path proj = "D:\\Projects\\lunarium\\test2"; std::filesystem::path Project::MakeRelativeToAssets(std::filesystem::path abs_path, bool include_root) const
std::filesystem::path new_path = proj.filename();
for (auto iter = p.begin(); iter != p.end(); iter++)
{ {
std::cout << "\n" << (*iter); return MakeRelativeTo(abs_path, GetAssetDirectory(), include_root);
if (proj.string().find((*iter).string()) == std::string::npos)
{
new_path /= (*iter);
}
} }
std::cout << "\nNew Path: " << new_path; // new_path is what should be used as the location of the asset!
*/
std::filesystem::path Project::MakeRelativeTo(std::filesystem::path abs_path, std::filesystem::path rel_to, bool include_root) const
{
// Validate the passed in path // Validate the passed in path
if (!abs_path.is_absolute()) if (!abs_path.is_absolute())
{ {
if (abs_path.filename() == std::filesystem::path(*mLocation.begin())) if (abs_path.filename() == std::filesystem::path(*rel_to.begin()))
{ {
// This path is already relative to the project root // This path is already relative to the project root
return abs_path; return abs_path;
@ -161,10 +156,12 @@ namespace lunarium { namespace editor
return ""; return "";
} }
std::filesystem::path new_path = mLocation.filename(); std::filesystem::path new_path;
if (include_root) new_path = rel_to.filename();
for (auto iter = abs_path.begin(); iter != abs_path.end(); iter++) for (auto iter = abs_path.begin(); iter != abs_path.end(); iter++)
{ {
if (mLocation.string().find((*iter).string()) == std::string::npos) if (rel_to.string().find((*iter).string()) == std::string::npos)
{ {
new_path /= (*iter); new_path /= (*iter);
} }

@ -40,7 +40,8 @@ namespace lunarium { namespace editor
std::filesystem::path GetAssetDirectory() const; std::filesystem::path GetAssetDirectory() const;
// Convert an absolute path to a path relative to the project root // Convert an absolute path to a path relative to the project root
std::filesystem::path MakeRelativeToRoot(std::filesystem::path) const; std::filesystem::path MakeRelativeToRoot(std::filesystem::path, bool include_root = false) const;
std::filesystem::path MakeRelativeToAssets(std::filesystem::path, bool include_root = false) const;
private: private:
bool mIsLoaded; bool mIsLoaded;
@ -52,6 +53,7 @@ namespace lunarium { namespace editor
private: private:
void LoadContent(); void LoadContent();
std::filesystem::path MakeRelativeTo(std::filesystem::path p, std::filesystem::path rel_to, bool include_root) const;
}; };
}} }}

@ -270,7 +270,7 @@ namespace lunarium { namespace editor
Logger::Info(Editor::LogCat, "Importing tile set: %s", path->string().c_str()); Logger::Info(Editor::LogCat, "Importing tile set: %s", path->string().c_str());
uint64_t id = 0; uint64_t id = 0;
ContentManager::GetInstance().ImportFile(*path, /*mpEditor->GetAssetBrowserLocation() / */ path->filename(), AssetType::EATYPE_TILE_SET, id).LogIfFailed(Editor::LogCat); ContentManager::GetInstance().ImportFile(*path, mpEditor->GetAssetBrowserLocation() / path->filename(), AssetType::EATYPE_TILE_SET, id).LogIfFailed(Editor::LogCat);
TileSet* ts = (TileSet*)ContentManager::GetInstance().GetAsset(id); TileSet* ts = (TileSet*)ContentManager::GetInstance().GetAsset(id);
ts->SetTileSize({16, 16}); // NOTE: Hardcoding the tile size for testing ts->SetTileSize({16, 16}); // NOTE: Hardcoding the tile size for testing

Loading…
Cancel
Save