ui: Add Windows directory selection

This commit is contained in:
Matt Borgerson 2022-05-07 21:42:52 -07:00 committed by mborgerson
parent 156c1edd2b
commit 41e9c669d9
3 changed files with 55 additions and 4 deletions

View File

@ -34,7 +34,7 @@ implot = declare_dependency(link_with: libimplot,
noc_ss = ss.source_set() noc_ss = ss.source_set()
noc_ss.add(when: 'CONFIG_LINUX', if_true: [xemu_gtk, files('noc_file_dialog/noc_file_dialog_gtk.c')]) noc_ss.add(when: 'CONFIG_LINUX', if_true: [xemu_gtk, files('noc_file_dialog/noc_file_dialog_gtk.c')])
noc_ss.add(when: 'CONFIG_WIN32', if_true: files('noc_file_dialog/noc_file_dialog_win32.c')) noc_ss.add(when: 'CONFIG_WIN32', if_true: files('noc_file_dialog/noc_file_dialog_win32.cc'))
noc_ss.add(when: 'CONFIG_DARWIN', if_true: files('noc_file_dialog/noc_file_dialog_macos.m')) noc_ss.add(when: 'CONFIG_DARWIN', if_true: files('noc_file_dialog/noc_file_dialog_macos.m'))
noc_ss = noc_ss.apply(config_all, strict: false) noc_ss = noc_ss.apply(config_all, strict: false)
noclib = static_library('noc', noclib = static_library('noc',

View File

@ -64,11 +64,20 @@ enum {
* managed by the library. The string is valid until the next call to * managed by the library. The string is valid until the next call to
* no_dialog_open. If the user canceled, the return value is NULL. * no_dialog_open. If the user canceled, the return value is NULL.
*/ */
#ifdef __cplusplus
extern "C" {
#endif
const char *noc_file_dialog_open(int flags, const char *noc_file_dialog_open(int flags,
const char *filters, const char *filters,
const char *default_path, const char *default_path,
const char *default_name); const char *default_name);
#ifdef __cplusplus
}
#endif
#ifdef NOC_FILE_DIALOG_IMPLEMENTATION #ifdef NOC_FILE_DIALOG_IMPLEMENTATION
#include <stdlib.h> #include <stdlib.h>
@ -164,16 +173,58 @@ const char *noc_file_dialog_open(int flags,
#ifdef NOC_FILE_DIALOG_WIN32 #ifdef NOC_FILE_DIALOG_WIN32
#define UNICODE 1
#include <windows.h> #include <windows.h>
#include <commdlg.h> #include <commdlg.h>
#include <glib.h> #include <glib.h>
#include <stdio.h> #include <stdio.h>
#include <combaseapi.h>
#include <shobjidl.h>
static const char *noc_file_dialog_open_folder(void)
{
const char *path = NULL;
IFileDialog *pfd;
if (SUCCEEDED(CoCreateInstance(CLSID_FileOpenDialog, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&pfd))))
{
DWORD dwOptions;
if (SUCCEEDED(pfd->GetOptions(&dwOptions)))
{
pfd->SetOptions(dwOptions | FOS_PICKFOLDERS);
}
if (SUCCEEDED(pfd->Show(NULL)))
{
IShellItem *pItem;
if (SUCCEEDED(pfd->GetResult(&pItem)))
{
PWSTR pszFilePath;
HRESULT hr = pItem->GetDisplayName(SIGDN_FILESYSPATH, &pszFilePath);
if (SUCCEEDED(hr))
{
path = g_utf16_to_utf8((gunichar2*)pszFilePath, -1, NULL, NULL, NULL);
CoTaskMemFree(pszFilePath);
}
pItem->Release();
}
}
pfd->Release();
}
return path;
}
const char *noc_file_dialog_open(int flags, const char *noc_file_dialog_open(int flags,
const char *filters, const char *filters,
const char *default_path, const char *default_path,
const char *default_name) const char *default_name)
{ {
if (flags & NOC_FILE_DIALOG_DIR) {
return noc_file_dialog_open_folder();
}
OPENFILENAMEW ofn; // common dialog box structure OPENFILENAMEW ofn; // common dialog box structure
wchar_t szFile[_MAX_PATH]; // buffer for file name wchar_t szFile[_MAX_PATH]; // buffer for file name
wchar_t initialDir[_MAX_PATH]; wchar_t initialDir[_MAX_PATH];
@ -200,14 +251,14 @@ const char *noc_file_dialog_open(int flags,
} }
} }
if (default_path) { if (default_path) {
wdefault_path = g_utf8_to_utf16(default_path, -1, NULL, NULL, NULL); wdefault_path = (wchar_t*)g_utf8_to_utf16(default_path, -1, NULL, NULL, NULL);
if (!wdefault_path) { if (!wdefault_path) {
fprintf(stderr, "Failed to convert UTF-8 string to UTF-16\n"); fprintf(stderr, "Failed to convert UTF-8 string to UTF-16\n");
goto done; goto done;
} }
} }
if (default_name) { if (default_name) {
wdefault_name = g_utf8_to_utf16(default_name, -1, NULL, NULL, NULL); wdefault_name = (wchar_t*)g_utf8_to_utf16(default_name, -1, NULL, NULL, NULL);
if (!wdefault_name) { if (!wdefault_name) {
fprintf(stderr, "Failed to convert UTF-8 string to UTF-16\n"); fprintf(stderr, "Failed to convert UTF-8 string to UTF-16\n");
goto done; goto done;
@ -247,7 +298,7 @@ done:
g_free(g_noc_file_dialog_ret); g_free(g_noc_file_dialog_ret);
if (ret) { if (ret) {
g_noc_file_dialog_ret = g_utf16_to_utf8(szFile, -1, NULL, NULL, NULL); g_noc_file_dialog_ret = g_utf16_to_utf8((gunichar2*)szFile, -1, NULL, NULL, NULL);
} else { } else {
g_noc_file_dialog_ret = NULL; g_noc_file_dialog_ret = NULL;
} }