Archived
1
Fork 0

Add imgui open/save dialog

This commit is contained in:
redstrate 2021-10-11 13:39:15 -04:00
parent 6fde122401
commit 182fbe195a
12 changed files with 101 additions and 33 deletions

View file

@ -248,6 +248,10 @@ namespace prism {
*/
void update_scene(Scene& scene);
imgui_backend& get_imgui() {
return *imgui;
}
/// The current cutscene.
std::unique_ptr<Cutscene> cutscene;

View file

@ -1,6 +1,7 @@
#pragma once
#include <string_view>
#include <filesystem>
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<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:
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;
};
}

View file

@ -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();
});

View file

@ -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<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;
}

View file

@ -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<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.
@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.

View file

@ -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<void(std::string)> returnFunction, bool openDirectory) {
}
void platform::save_dialog(std::function<void(std::string)> returnFunction) {
}
char* platform::translate_keycode(const unsigned int keycode) {
return const_cast<char*>(SDL_GetKeyName(SDL_GetKeyFromScancode((SDL_Scancode)keycode)));
}

View file

@ -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)

View file

@ -47,11 +47,7 @@ const std::map<ImGuiKey, InputButton> 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;

View file

@ -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);

View file

@ -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);

View file

@ -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);

View file

@ -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);
});
}