diff --git a/engine/core/include/engine.hpp b/engine/core/include/engine.hpp index 30fa471..69f513a 100755 --- a/engine/core/include/engine.hpp +++ b/engine/core/include/engine.hpp @@ -248,6 +248,10 @@ namespace prism { */ void update_scene(Scene& scene); + imgui_backend& get_imgui() { + return *imgui; + } + /// The current cutscene. std::unique_ptr cutscene; diff --git a/engine/core/include/imgui_backend.hpp b/engine/core/include/imgui_backend.hpp index 5b302da..6502ac8 100644 --- a/engine/core/include/imgui_backend.hpp +++ b/engine/core/include/imgui_backend.hpp @@ -1,6 +1,7 @@ #pragma once #include +#include namespace prism { class imgui_backend { @@ -18,7 +19,31 @@ namespace prism { void process_text_input(const std::string_view string); + /**Opens a file dialog to select a file. This will not block. + @param existing Whether or not to limit to existing files. + @param returnFunction The callback function when a file is selected or the dialog is cancelled. An empy string is returned when cancelled. + @param openDirectory Whether or not to allow selecting directories as well. + */ + void open_dialog(const bool existing, std::function returnFunction, bool openDirectory = false); + + /**Opens a file dialog to select a save location for a file. This will not block. + @param returnFunction The callback function when a file is selected or the dialog is cancelled. An empy string is returned when cancelled. + */ + void save_dialog(std::function returnFunction); + private: bool mouse_buttons[3] = {}; + + bool open_dialog_next_frame = false; + bool save_dialog_next_frame = false; + + struct dialog_data { + std::filesystem::path current_path; + std::filesystem::path selected_path; + std::function return_function; + }; + + dialog_data open_dialog_data; + dialog_data save_dialog_data; }; } \ No newline at end of file diff --git a/engine/core/src/debug.cpp b/engine/core/src/debug.cpp index 2007b73..5d4635f 100644 --- a/engine/core/src/debug.cpp +++ b/engine/core/src/debug.cpp @@ -13,6 +13,7 @@ #include "renderer.hpp" #include "file.hpp" #include "console.hpp" +#include "imgui_backend.hpp" struct Options { std::string shader_source_path; @@ -169,7 +170,7 @@ void draw_shader_editor() { if(options.shader_source_path.empty()) { ImGui::Text("You haven't specified a shader source path yet. Please select one below:"); if(ImGui::Button("Select Path")) { - platform::open_dialog(false, [](std::string path) { + engine->get_imgui().open_dialog(false, [](std::string path) { // open_dialog() can't select folders yet, so use this as a workaround options.shader_source_path = prism::path(path).parent_path().string(); }); diff --git a/engine/core/src/imgui_backend.cpp b/engine/core/src/imgui_backend.cpp index 05ad732..9f61ce7 100644 --- a/engine/core/src/imgui_backend.cpp +++ b/engine/core/src/imgui_backend.cpp @@ -204,6 +204,50 @@ void imgui_backend::begin_frame(const float delta_time) { mouse_buttons[0] = mouse_buttons[1] = mouse_buttons[2] = false; ImGui::NewFrame(); + + if(open_dialog_next_frame) { + ImGui::OpenPopup("Open File"); + open_dialog_next_frame = false; + } + + if(save_dialog_next_frame) { + ImGui::OpenPopup("Save File"); + save_dialog_next_frame = false; + } + + const auto dialog_function = [](dialog_data& data) { + if(ImGui::Selectable("..", false, ImGuiSelectableFlags_DontClosePopups)) + data.current_path = data.current_path.parent_path(); + + for(auto dir_ent : std::filesystem::directory_iterator(data.current_path)) { + if(ImGui::Selectable(dir_ent.path().c_str(), data.selected_path == dir_ent.path(), ImGuiSelectableFlags_DontClosePopups)) { + if(dir_ent.is_directory()) + data.current_path = dir_ent.path(); + else + data.selected_path = dir_ent.path(); + } + } + + ImGui::TextDisabled("Selected: %s", data.selected_path.c_str()); + + if(ImGui::Button("OK")) { + data.return_function(data.selected_path.string()); + ImGui::CloseCurrentPopup(); + } + + if(ImGui::Button("Cancel")) + ImGui::CloseCurrentPopup(); + }; + + if(ImGui::BeginPopup("Open File")) { + dialog_function(open_dialog_data); + ImGui::EndPopup(); + } + + if(ImGui::BeginPopup("Save File")) { + dialog_function(save_dialog_data); + ImGui::EndPopup(); + } } void imgui_backend::render(int index) { @@ -239,3 +283,15 @@ void prism::imgui_backend::process_text_input(const std::string_view string) { ImGuiIO& io = ImGui::GetIO(); io.AddInputCharactersUTF8(string.data()); } + +void prism::imgui_backend::open_dialog(const bool existing, std::function returnFunction, bool openDirectory) { + open_dialog_next_frame = true; + open_dialog_data.current_path = std::filesystem::current_path(); + open_dialog_data.return_function = returnFunction; +} + +void prism::imgui_backend::save_dialog(std::function returnFunction) { + save_dialog_next_frame = true; + save_dialog_data.current_path = std::filesystem::current_path(); + save_dialog_data.return_function = returnFunction; +} \ No newline at end of file diff --git a/engine/platform/include/platform.hpp b/engine/platform/include/platform.hpp index 0c35556..1789a3b 100755 --- a/engine/platform/include/platform.hpp +++ b/engine/platform/include/platform.hpp @@ -163,18 +163,6 @@ namespace platform { void begin_text_input(); void end_text_input(); - /**Opens a file dialog to select a file. This will not block. - @param existing Whether or not to limit to existing files. - @param returnFunction The callback function when a file is selected or the dialog is cancelled. An empy string is returned when cancelled. - @param openDirectory Whether or not to allow selecting directories as well. - */ - void open_dialog(const bool existing, std::function returnFunction, bool openDirectory = false); - - /**Opens a file dialog to select a save location for a file. This will not block. - @param returnFunction The callback function when a file is selected or the dialog is cancelled. An empy string is returned when cancelled. - */ - void save_dialog(std::function returnFunction); - /**Translates a virtual keycode to it's character equivalent. @note Example: translateKey(0x01) = 'a'; 0x01 in this example is a platform and language specific keycode for a key named 'a'. @return A char pointer to the string if translated correctly. diff --git a/platforms/sdl/main.cpp.in b/platforms/sdl/main.cpp.in index cf38c66..7741930 100644 --- a/platforms/sdl/main.cpp.in +++ b/platforms/sdl/main.cpp.in @@ -257,12 +257,6 @@ void platform::capture_mouse(const bool capture) { SDL_CaptureMouse((SDL_bool)capture); } -void platform::open_dialog(const bool existing, std::function returnFunction, bool openDirectory) { -} - -void platform::save_dialog(std::function returnFunction) { -} - char* platform::translate_keycode(const unsigned int keycode) { return const_cast(SDL_GetKeyName(SDL_GetKeyFromScancode((SDL_Scancode)keycode))); } diff --git a/tools/common/include/commoneditor.hpp b/tools/common/include/commoneditor.hpp index 7b980b7..dcee9ac 100755 --- a/tools/common/include/commoneditor.hpp +++ b/tools/common/include/commoneditor.hpp @@ -21,6 +21,7 @@ #include "asset.hpp" #include "scene.hpp" #include "renderer.hpp" +#include "imgui_backend.hpp" class TransformCommand : public Command { public: @@ -359,7 +360,7 @@ inline void editPath(const char* label, std::string& path, bool editable = true, ImGui::SameLine(); if(ImGui::Button("...")) { - platform::open_dialog(false, [&path, &on_selected](std::string p) { + engine->get_imgui().open_dialog(false, [&path, &on_selected](std::string p) { path = prism::get_relative_path(prism::domain::app, p).string(); if(on_selected != nullptr) diff --git a/tools/common/src/commoneditor.cpp b/tools/common/src/commoneditor.cpp index 0838449..5cf447a 100755 --- a/tools/common/src/commoneditor.cpp +++ b/tools/common/src/commoneditor.cpp @@ -47,11 +47,7 @@ const std::map imToPl = { }; CommonEditor::CommonEditor(std::string id) : id(id) { -#ifdef PLATFORM_MACOS - prism::set_domain_path(prism::domain::app, "../../../data"); -#else - prism::set_domain_path(prism::domain::app, "data"); -#endif + prism::set_domain_path(prism::domain::app, "{resource_dir}/data"); prism::set_domain_path(prism::domain::internal, "{resource_dir}/shaders"); ImGuiIO& io = ImGui::GetIO(); @@ -730,6 +726,9 @@ void cacheAssetFilesystem() { asset_files.clear(); auto data_directory = "data"; + if(!std::filesystem::exists(data_directory)) + return; + for(auto& p : std::filesystem::recursive_directory_iterator(data_directory)) { if(p.path().extension() == ".model" && mesh_readable(p.path())) { asset_files[std::filesystem::relative(p, data_directory)] = AssetType::Mesh; diff --git a/tools/editor/src/materialeditor.cpp b/tools/editor/src/materialeditor.cpp index c0f633d..1a2d6df 100755 --- a/tools/editor/src/materialeditor.cpp +++ b/tools/editor/src/materialeditor.cpp @@ -131,7 +131,7 @@ void MaterialEditor::draw(CommonEditor* editor) { if (ImGui::BeginMenu("File")) { if(ImGui::MenuItem("Save", "CTRL+S")) { if (path.empty()) { - platform::save_dialog([this](std::string path) { + engine->get_imgui().save_dialog([this](std::string path) { this->path = path; save_material(*material, path); @@ -142,7 +142,7 @@ void MaterialEditor::draw(CommonEditor* editor) { } if (ImGui::MenuItem("Save as...", "CTRL+S")) { - platform::save_dialog([this](std::string path) { + engine->get_imgui().save_dialog([this](std::string path) { this->path = path; save_material(*material, path); diff --git a/tools/editor/src/prefabeditor.cpp b/tools/editor/src/prefabeditor.cpp index c614e50..be930b5 100755 --- a/tools/editor/src/prefabeditor.cpp +++ b/tools/editor/src/prefabeditor.cpp @@ -36,7 +36,7 @@ void PrefabEditor::draw(CommonEditor* editor) { if (ImGui::BeginMenu("File")) { if(ImGui::MenuItem("Save", "CTRL+S")) { if (path.empty()) { - platform::save_dialog([this](std::string path) { + engine->get_imgui().save_dialog([this](std::string path) { this->path = path; engine->save_prefab(root_object, path); @@ -47,7 +47,7 @@ void PrefabEditor::draw(CommonEditor* editor) { } if (ImGui::MenuItem("Save as...", "CTRL+S")) { - platform::save_dialog([this](std::string path) { + engine->get_imgui().save_dialog([this](std::string path) { this->path = path; engine->save_prefab(root_object, path); diff --git a/tools/editor/src/prismeditor.cpp b/tools/editor/src/prismeditor.cpp index 1af48d9..6eb41ea 100755 --- a/tools/editor/src/prismeditor.cpp +++ b/tools/editor/src/prismeditor.cpp @@ -226,7 +226,7 @@ void PrismEditor::drawUI() { } if(ImGui::MenuItem("Open", "CTRL+O")) { - platform::open_dialog(true, [this](std::string path) { + engine->get_imgui().open_dialog(true, [this](std::string path) { open_requests.emplace_back(path, false); addOpenedFile(path); diff --git a/tools/editor/src/sceneeditor.cpp b/tools/editor/src/sceneeditor.cpp index c5ab0be..e43c714 100755 --- a/tools/editor/src/sceneeditor.cpp +++ b/tools/editor/src/sceneeditor.cpp @@ -44,7 +44,7 @@ void SceneEditor::draw(CommonEditor* editor) { if (ImGui::BeginMenu("File")) { if(ImGui::MenuItem("Save", "CTRL+S")) { if (path.empty()) { - platform::save_dialog([this](std::string path) { + engine->get_imgui().save_dialog([this](std::string path) { this->path = path; engine->save_scene(path); @@ -55,7 +55,7 @@ void SceneEditor::draw(CommonEditor* editor) { } if(ImGui::MenuItem("Save as...", "CTRL+S")) { - platform::save_dialog([this](std::string path) { + engine->get_imgui().save_dialog([this](std::string path) { this->path = path; engine->save_scene(path); @@ -107,7 +107,7 @@ void SceneEditor::draw(CommonEditor* editor) { } if(ImGui::MenuItem("Prefab")) { - platform::open_dialog(false, [](std::string path) { + engine->get_imgui().open_dialog(false, [](std::string path) { engine->add_prefab(*engine->get_scene(), path); }); }