From 55bfc0153aba592ba5254adaefaa6d3b13143f99 Mon Sep 17 00:00:00 2001 From: Mr-Wiseguy Date: Mon, 14 Apr 2025 17:18:13 -0400 Subject: [PATCH] Use a multiple file select dialog for mod install button --- include/zelda_support.h | 2 ++ src/main/support.cpp | 33 +++++++++++++++++++++++++++++++++ src/ui/ui_mod_menu.cpp | 4 ++-- 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/include/zelda_support.h b/include/zelda_support.h index 9751e9a..89b66f0 100644 --- a/include/zelda_support.h +++ b/include/zelda_support.h @@ -3,10 +3,12 @@ #include #include +#include namespace zelda64 { std::filesystem::path get_asset_path(const char* asset); void open_file_dialog(std::function callback); + void open_file_dialog_multiple(std::function& paths)> callback); void show_error_message_box(const char *title, const char *message); // Apple specific methods that usually require Objective-C. Implemented in support_apple.mm. diff --git a/src/main/support.cpp b/src/main/support.cpp index dee5f5d..53f00b1 100644 --- a/src/main/support.cpp +++ b/src/main/support.cpp @@ -20,6 +20,29 @@ namespace zelda64 { callback(success, path); } + void perform_file_dialog_operation_multiple(const std::function&)>& callback) { + const nfdpathset_t* native_paths = nullptr; + nfdresult_t result = NFD_OpenDialogMultipleN(&native_paths, nullptr, 0, nullptr); + + bool success = (result == NFD_OKAY); + std::list paths; + nfdpathsetsize_t count = 0; + + if (success) { + NFD_PathSet_GetCount(native_paths, &count); + for (nfdpathsetsize_t i = 0; i < count; i++) { + nfdnchar_t* cur_path = nullptr; + nfdresult_t cur_result = NFD_PathSet_GetPathN(native_paths, i, &cur_path); + if (cur_result == NFD_OKAY) { + paths.emplace_back(std::filesystem::path{cur_path}); + } + } + NFD_PathSet_Free(native_paths); + } + + callback(success, paths); + } + // MARK: - Public API std::filesystem::path get_asset_path(const char* asset) { @@ -41,6 +64,16 @@ namespace zelda64 { #endif } + void open_file_dialog_multiple(std::function& paths)> callback) { +#ifdef __APPLE__ + dispatch_on_ui_thread([callback]() { + perform_file_dialog_operation_multiple(callback); + }); +#else + perform_file_dialog_operation_multiple(callback); +#endif + } + void show_error_message_box(const char *title, const char *message) { #ifdef __APPLE__ std::string title_copy(title); diff --git a/src/ui/ui_mod_menu.cpp b/src/ui/ui_mod_menu.cpp index 2879f9f..b9e06c8 100644 --- a/src/ui/ui_mod_menu.cpp +++ b/src/ui/ui_mod_menu.cpp @@ -243,11 +243,11 @@ void ModMenu::open_mods_folder() { } void ModMenu::open_install_dialog() { - zelda64::open_file_dialog([](bool success, const std::filesystem::path& path) { + zelda64::open_file_dialog_multiple([](bool success, const std::list& paths) { if (success) { ContextId old_context = recompui::try_close_current_context(); - recompui::drop_files({ path }); + recompui::drop_files(paths); if (old_context != ContextId::null()) { old_context.open();