Add imgui open/save dialog
This commit is contained in:
parent
6fde122401
commit
182fbe195a
12 changed files with 101 additions and 33 deletions
|
@ -248,6 +248,10 @@ namespace prism {
|
||||||
*/
|
*/
|
||||||
void update_scene(Scene& scene);
|
void update_scene(Scene& scene);
|
||||||
|
|
||||||
|
imgui_backend& get_imgui() {
|
||||||
|
return *imgui;
|
||||||
|
}
|
||||||
|
|
||||||
/// The current cutscene.
|
/// The current cutscene.
|
||||||
std::unique_ptr<Cutscene> cutscene;
|
std::unique_ptr<Cutscene> cutscene;
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
|
|
||||||
#include <string_view>
|
#include <string_view>
|
||||||
|
#include <filesystem>
|
||||||
|
|
||||||
namespace prism {
|
namespace prism {
|
||||||
class imgui_backend {
|
class imgui_backend {
|
||||||
|
@ -18,7 +19,31 @@ namespace prism {
|
||||||
|
|
||||||
void process_text_input(const std::string_view string);
|
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<void(std::string)> 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<void(std::string)> returnFunction);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool mouse_buttons[3] = {};
|
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<void(std::string)> return_function;
|
||||||
|
};
|
||||||
|
|
||||||
|
dialog_data open_dialog_data;
|
||||||
|
dialog_data save_dialog_data;
|
||||||
};
|
};
|
||||||
}
|
}
|
|
@ -13,6 +13,7 @@
|
||||||
#include "renderer.hpp"
|
#include "renderer.hpp"
|
||||||
#include "file.hpp"
|
#include "file.hpp"
|
||||||
#include "console.hpp"
|
#include "console.hpp"
|
||||||
|
#include "imgui_backend.hpp"
|
||||||
|
|
||||||
struct Options {
|
struct Options {
|
||||||
std::string shader_source_path;
|
std::string shader_source_path;
|
||||||
|
@ -169,7 +170,7 @@ void draw_shader_editor() {
|
||||||
if(options.shader_source_path.empty()) {
|
if(options.shader_source_path.empty()) {
|
||||||
ImGui::Text("You haven't specified a shader source path yet. Please select one below:");
|
ImGui::Text("You haven't specified a shader source path yet. Please select one below:");
|
||||||
if(ImGui::Button("Select Path")) {
|
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
|
// open_dialog() can't select folders yet, so use this as a workaround
|
||||||
options.shader_source_path = prism::path(path).parent_path().string();
|
options.shader_source_path = prism::path(path).parent_path().string();
|
||||||
});
|
});
|
||||||
|
|
|
@ -204,6 +204,50 @@ void imgui_backend::begin_frame(const float delta_time) {
|
||||||
mouse_buttons[0] = mouse_buttons[1] = mouse_buttons[2] = false;
|
mouse_buttons[0] = mouse_buttons[1] = mouse_buttons[2] = false;
|
||||||
|
|
||||||
ImGui::NewFrame();
|
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) {
|
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();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
io.AddInputCharactersUTF8(string.data());
|
io.AddInputCharactersUTF8(string.data());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void prism::imgui_backend::open_dialog(const bool existing, std::function<void(std::string)> 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<void(std::string)> returnFunction) {
|
||||||
|
save_dialog_next_frame = true;
|
||||||
|
save_dialog_data.current_path = std::filesystem::current_path();
|
||||||
|
save_dialog_data.return_function = returnFunction;
|
||||||
|
}
|
|
@ -163,18 +163,6 @@ namespace platform {
|
||||||
void begin_text_input();
|
void begin_text_input();
|
||||||
void end_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<void(std::string)> 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<void(std::string)> returnFunction);
|
|
||||||
|
|
||||||
/**Translates a virtual keycode to it's character equivalent.
|
/**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'.
|
@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.
|
@return A char pointer to the string if translated correctly.
|
||||||
|
|
|
@ -257,12 +257,6 @@ void platform::capture_mouse(const bool capture) {
|
||||||
SDL_CaptureMouse((SDL_bool)capture);
|
SDL_CaptureMouse((SDL_bool)capture);
|
||||||
}
|
}
|
||||||
|
|
||||||
void platform::open_dialog(const bool existing, std::function<void(std::string)> returnFunction, bool openDirectory) {
|
|
||||||
}
|
|
||||||
|
|
||||||
void platform::save_dialog(std::function<void(std::string)> returnFunction) {
|
|
||||||
}
|
|
||||||
|
|
||||||
char* platform::translate_keycode(const unsigned int keycode) {
|
char* platform::translate_keycode(const unsigned int keycode) {
|
||||||
return const_cast<char*>(SDL_GetKeyName(SDL_GetKeyFromScancode((SDL_Scancode)keycode)));
|
return const_cast<char*>(SDL_GetKeyName(SDL_GetKeyFromScancode((SDL_Scancode)keycode)));
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,7 @@
|
||||||
#include "asset.hpp"
|
#include "asset.hpp"
|
||||||
#include "scene.hpp"
|
#include "scene.hpp"
|
||||||
#include "renderer.hpp"
|
#include "renderer.hpp"
|
||||||
|
#include "imgui_backend.hpp"
|
||||||
|
|
||||||
class TransformCommand : public Command {
|
class TransformCommand : public Command {
|
||||||
public:
|
public:
|
||||||
|
@ -359,7 +360,7 @@ inline void editPath(const char* label, std::string& path, bool editable = true,
|
||||||
ImGui::SameLine();
|
ImGui::SameLine();
|
||||||
|
|
||||||
if(ImGui::Button("...")) {
|
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();
|
path = prism::get_relative_path(prism::domain::app, p).string();
|
||||||
|
|
||||||
if(on_selected != nullptr)
|
if(on_selected != nullptr)
|
||||||
|
|
|
@ -47,11 +47,7 @@ const std::map<ImGuiKey, InputButton> imToPl = {
|
||||||
};
|
};
|
||||||
|
|
||||||
CommonEditor::CommonEditor(std::string id) : id(id) {
|
CommonEditor::CommonEditor(std::string id) : id(id) {
|
||||||
#ifdef PLATFORM_MACOS
|
prism::set_domain_path(prism::domain::app, "{resource_dir}/data");
|
||||||
prism::set_domain_path(prism::domain::app, "../../../data");
|
|
||||||
#else
|
|
||||||
prism::set_domain_path(prism::domain::app, "data");
|
|
||||||
#endif
|
|
||||||
prism::set_domain_path(prism::domain::internal, "{resource_dir}/shaders");
|
prism::set_domain_path(prism::domain::internal, "{resource_dir}/shaders");
|
||||||
|
|
||||||
ImGuiIO& io = ImGui::GetIO();
|
ImGuiIO& io = ImGui::GetIO();
|
||||||
|
@ -730,6 +726,9 @@ void cacheAssetFilesystem() {
|
||||||
asset_files.clear();
|
asset_files.clear();
|
||||||
|
|
||||||
auto data_directory = "data";
|
auto data_directory = "data";
|
||||||
|
if(!std::filesystem::exists(data_directory))
|
||||||
|
return;
|
||||||
|
|
||||||
for(auto& p : std::filesystem::recursive_directory_iterator(data_directory)) {
|
for(auto& p : std::filesystem::recursive_directory_iterator(data_directory)) {
|
||||||
if(p.path().extension() == ".model" && mesh_readable(p.path())) {
|
if(p.path().extension() == ".model" && mesh_readable(p.path())) {
|
||||||
asset_files[std::filesystem::relative(p, data_directory)] = AssetType::Mesh;
|
asset_files[std::filesystem::relative(p, data_directory)] = AssetType::Mesh;
|
||||||
|
|
|
@ -131,7 +131,7 @@ void MaterialEditor::draw(CommonEditor* editor) {
|
||||||
if (ImGui::BeginMenu("File")) {
|
if (ImGui::BeginMenu("File")) {
|
||||||
if(ImGui::MenuItem("Save", "CTRL+S")) {
|
if(ImGui::MenuItem("Save", "CTRL+S")) {
|
||||||
if (path.empty()) {
|
if (path.empty()) {
|
||||||
platform::save_dialog([this](std::string path) {
|
engine->get_imgui().save_dialog([this](std::string path) {
|
||||||
this->path = path;
|
this->path = path;
|
||||||
|
|
||||||
save_material(*material, path);
|
save_material(*material, path);
|
||||||
|
@ -142,7 +142,7 @@ void MaterialEditor::draw(CommonEditor* editor) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::MenuItem("Save as...", "CTRL+S")) {
|
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;
|
this->path = path;
|
||||||
|
|
||||||
save_material(*material, path);
|
save_material(*material, path);
|
||||||
|
|
|
@ -36,7 +36,7 @@ void PrefabEditor::draw(CommonEditor* editor) {
|
||||||
if (ImGui::BeginMenu("File")) {
|
if (ImGui::BeginMenu("File")) {
|
||||||
if(ImGui::MenuItem("Save", "CTRL+S")) {
|
if(ImGui::MenuItem("Save", "CTRL+S")) {
|
||||||
if (path.empty()) {
|
if (path.empty()) {
|
||||||
platform::save_dialog([this](std::string path) {
|
engine->get_imgui().save_dialog([this](std::string path) {
|
||||||
this->path = path;
|
this->path = path;
|
||||||
|
|
||||||
engine->save_prefab(root_object, path);
|
engine->save_prefab(root_object, path);
|
||||||
|
@ -47,7 +47,7 @@ void PrefabEditor::draw(CommonEditor* editor) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ImGui::MenuItem("Save as...", "CTRL+S")) {
|
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;
|
this->path = path;
|
||||||
|
|
||||||
engine->save_prefab(root_object, path);
|
engine->save_prefab(root_object, path);
|
||||||
|
|
|
@ -226,7 +226,7 @@ void PrismEditor::drawUI() {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ImGui::MenuItem("Open", "CTRL+O")) {
|
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);
|
open_requests.emplace_back(path, false);
|
||||||
|
|
||||||
addOpenedFile(path);
|
addOpenedFile(path);
|
||||||
|
|
|
@ -44,7 +44,7 @@ void SceneEditor::draw(CommonEditor* editor) {
|
||||||
if (ImGui::BeginMenu("File")) {
|
if (ImGui::BeginMenu("File")) {
|
||||||
if(ImGui::MenuItem("Save", "CTRL+S")) {
|
if(ImGui::MenuItem("Save", "CTRL+S")) {
|
||||||
if (path.empty()) {
|
if (path.empty()) {
|
||||||
platform::save_dialog([this](std::string path) {
|
engine->get_imgui().save_dialog([this](std::string path) {
|
||||||
this->path = path;
|
this->path = path;
|
||||||
|
|
||||||
engine->save_scene(path);
|
engine->save_scene(path);
|
||||||
|
@ -55,7 +55,7 @@ void SceneEditor::draw(CommonEditor* editor) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ImGui::MenuItem("Save as...", "CTRL+S")) {
|
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;
|
this->path = path;
|
||||||
|
|
||||||
engine->save_scene(path);
|
engine->save_scene(path);
|
||||||
|
@ -107,7 +107,7 @@ void SceneEditor::draw(CommonEditor* editor) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ImGui::MenuItem("Prefab")) {
|
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);
|
engine->add_prefab(*engine->get_scene(), path);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
Reference in a new issue