From 8e5016e39e8f86ec37135ba1e3074ccb3b6e0bfd Mon Sep 17 00:00:00 2001 From: arpit agarwal Date: Tue, 12 Sep 2023 14:52:41 -0500 Subject: [PATCH] directory dialog based on https://github.com/mitsuba-renderer/nanogui/pull/48 --- include/nanogui/common.h | 9 ++++++ src/common.cpp | 62 ++++++++++++++++++++++++++++++++++++++++ src/darwin.mm | 18 ++++++++++++ src/python/main.cpp | 1 + 4 files changed, 90 insertions(+) diff --git a/include/nanogui/common.h b/include/nanogui/common.h index 2f38fe46..a0378833 100644 --- a/include/nanogui/common.h +++ b/include/nanogui/common.h @@ -274,6 +274,15 @@ extern NANOGUI_EXPORT std::string file_dialog(const std::vector> &filetypes, bool save); +/** +* \brief Open a native directory dialog. +* +* +* \param saved_path +* Optional parameter to specify a directory that the dialog should start in. +*/ + extern NANOGUI_EXPORT std::string + directory_dialog(std::string saved_path = ""); /** * \brief Check for the availability of displays with 10-bit color and/or diff --git a/src/common.cpp b/src/common.cpp index 77cef26b..21285227 100644 --- a/src/common.cpp +++ b/src/common.cpp @@ -16,6 +16,7 @@ # define NOMINMAX 1 # endif # include +# include #endif #include @@ -441,6 +442,67 @@ std::vector file_dialog(const std::vector 0 ){ + cmd += "--filename="+save_dir; + } + + FILE *output = popen(cmd.c_str(), "r"); + if (output == nullptr) + throw std::runtime_error("popen() failed -- could not launch zenity!"); + while (fgets(buffer, DIRECTORY_DIALOG_MAX_BUFFER, output) != NULL); + pclose(output); + std::string path(buffer); + + path.erase(std::remove(path.begin(), path.end(), '\n'), path.end()); + + return path; + + }; + #else + + + std::string directory_dialog(const std::string saved_path){ + TCHAR path[MAX_PATH]; + + const char * path_param = saved_path.c_str(); + + BROWSEINFO browseInfo = { 0 }; + browseInfo.lpszTitle = ("Select directory"); + browseInfo.ulFlags = BIF_RETURNONLYFSDIRS | BIF_NEWDIALOGSTYLE | BIF_EDITBOX | BIF_BROWSEINCLUDEURLS; + browseInfo.lParam = (LPARAM) path_param; + + LPITEMIDLIST pidl = SHBrowseForFolder ( &browseInfo ); + + if( pidl == 0 ){ + return ""; + }else{ + //get path + SHGetPathFromIDList ( pidl, path ); + + //free memory + IMalloc * imalloc = 0; + + if ( SUCCEEDED( SHGetMalloc ( &imalloc )) ){ + imalloc->Free(pidl); + imalloc->Release(); + } + + return path; + } + } + + #endif +#endif + static void (*object_inc_ref_py)(PyObject *) noexcept = nullptr; static void (*object_dec_ref_py)(PyObject *) noexcept = nullptr; diff --git a/src/darwin.mm b/src/darwin.mm index 83d448fa..4d99855e 100644 --- a/src/darwin.mm +++ b/src/darwin.mm @@ -56,6 +56,24 @@ @interface NSScreen (ForwardDeclare) return result; } +std::string directory_dialog(const std::string saved_path) { + NSOpenPanel *openDlg = [NSOpenPanel openPanel]; + + if(saved_path.length() > 0 ){ + std::string urlString = "folder"+saved_path; + [openDlg setDirectoryURL: [NSURL URLWithString: [NSString stringWithUTF8String: urlString.c_str()]]]; + } + [openDlg setCanChooseFiles:NO]; + [openDlg setCanChooseDirectories:YES]; + [openDlg setAllowsMultipleSelection:NO]; + + if ([openDlg runModal] == NSModalResponseOK) { + NSURL* url = [openDlg URL]; + return ((char*) [[url path] UTF8String]); + } + return ""; +} + void chdir_to_bundle_parent() { NSString *path = [[[NSBundle mainBundle] bundlePath] stringByDeletingLastPathComponent]; chdir([path fileSystemRepresentation]); diff --git a/src/python/main.cpp b/src/python/main.cpp index affbfca3..8b9f4374 100644 --- a/src/python/main.cpp +++ b/src/python/main.cpp @@ -111,6 +111,7 @@ NB_MODULE(nanogui_ext, m_) { bool)) & nanogui::file_dialog, D(file_dialog, 2)); + m.def("directory_dialog", &nanogui::directory_dialog); #if defined(__APPLE__) m.def("chdir_to_bundle_parent", &nanogui::chdir_to_bundle_parent); #endif