GUI: system file picker ins preview! (Windows)

This commit is contained in:
tildearrow 2022-06-19 01:36:36 -05:00
parent 03e31c441e
commit 52328df8c3
4 changed files with 108 additions and 14 deletions

View File

@ -11,10 +11,13 @@
#define _NFD_H
#include <stddef.h>
#include <functional>
/* denotes UTF-8 char */
typedef char nfdchar_t;
typedef std::function<void(const char*)> nfdselcallback_t;
/* opaque data structure -- see NFD_PathSet_* */
typedef struct {
nfdchar_t *buf;
@ -34,17 +37,20 @@ typedef enum {
/* single file open dialog */
nfdresult_t NFD_OpenDialog( const nfdchar_t *filterList,
const nfdchar_t *defaultPath,
nfdchar_t **outPath );
nfdchar_t **outPath,
nfdselcallback_t selCallback = NULL );
/* multiple file open dialog */
nfdresult_t NFD_OpenDialogMultiple( const nfdchar_t *filterList,
const nfdchar_t *defaultPath,
nfdpathset_t *outPaths );
nfdpathset_t *outPaths,
nfdselcallback_t selCallback = NULL );
/* save dialog */
nfdresult_t NFD_SaveDialog( const nfdchar_t *filterList,
const nfdchar_t *defaultPath,
nfdchar_t **outPath );
nfdchar_t **outPath,
nfdselcallback_t selCallback = NULL );
/* select folder dialog */

View File

@ -127,7 +127,8 @@ static nfdresult_t AllocPathSet( NSArray *urls, nfdpathset_t *pathset )
nfdresult_t NFD_OpenDialog( const nfdchar_t *filterList,
const nfdchar_t *defaultPath,
nfdchar_t **outPath )
nfdchar_t **outPath,
nfdselcallback_t selCallback )
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
@ -169,7 +170,8 @@ nfdresult_t NFD_OpenDialog( const nfdchar_t *filterList,
nfdresult_t NFD_OpenDialogMultiple( const nfdchar_t *filterList,
const nfdchar_t *defaultPath,
nfdpathset_t *outPaths )
nfdpathset_t *outPaths,
nfdselcallback_t selCallback )
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSWindow *keyWindow = [[NSApplication sharedApplication] keyWindow];
@ -213,7 +215,8 @@ nfdresult_t NFD_OpenDialogMultiple( const nfdchar_t *filterList,
nfdresult_t NFD_SaveDialog( const nfdchar_t *filterList,
const nfdchar_t *defaultPath,
nfdchar_t **outPath )
nfdchar_t **outPath,
nfdselcallback_t selCallback )
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
NSWindow *keyWindow = [[NSApplication sharedApplication] keyWindow];

View File

@ -27,6 +27,72 @@
#include <shobjidl.h>
#include "nfd_common.h"
// hack I know
#include "../../../src/utfutils.h"
class NFDWinEvents: public IFileDialogEvents {
nfdselcallback_t selCallback;
size_t refCount;
virtual ~NFDWinEvents() {
}
public:
IFACEMETHODIMP QueryInterface(REFIID riid, void** ppv) {
printf("QueryInterface called DAMN IT\n");
*ppv=NULL;
return E_NOTIMPL;
}
IFACEMETHODIMP_(ULONG) AddRef() {
printf("AddRef() called\n");
return InterlockedIncrement(&refCount);
}
IFACEMETHODIMP_(ULONG) Release() {
printf("Release() called\n");
LONG ret=InterlockedDecrement(&refCount);
if (ret==0) {
printf("Destroying the final object.\n");
delete this;
}
return ret;
}
IFACEMETHODIMP OnFileOk(IFileDialog*) { return E_NOTIMPL; }
IFACEMETHODIMP OnFolderChange(IFileDialog*) { return E_NOTIMPL; }
IFACEMETHODIMP OnFolderChanging(IFileDialog*, IShellItem*) { return E_NOTIMPL; }
IFACEMETHODIMP OnOverwrite(IFileDialog*, IShellItem*, FDE_OVERWRITE_RESPONSE*) { return E_NOTIMPL; }
IFACEMETHODIMP OnShareViolation(IFileDialog*, IShellItem*, FDE_SHAREVIOLATION_RESPONSE*) { return E_NOTIMPL; }
IFACEMETHODIMP OnTypeChange(IFileDialog*) { return E_NOTIMPL; }
IFACEMETHODIMP OnSelectionChange(IFileDialog* dialog) {
// Get the file name
::IShellItem *shellItem(NULL);
HRESULT result = dialog->GetCurrentSelection(&shellItem);
if ( !SUCCEEDED(result) )
{
printf("failure!\n");
return S_OK;
}
wchar_t *filePath(NULL);
result = shellItem->GetDisplayName(::SIGDN_FILESYSPATH, &filePath);
if ( !SUCCEEDED(result) )
{
printf("GDN failure!\n");
shellItem->Release();
return S_OK;
}
std::string utf8FilePath=utf16To8(filePath);
if (selCallback!=NULL) selCallback(utf8FilePath.c_str());
printf("I got you for a value of %s\n",utf8FilePath.c_str());
shellItem->Release();
return S_OK;
}
NFDWinEvents(nfdselcallback_t callback):
selCallback(callback),
refCount(1) {
}
};
#define COM_INITFLAGS ::COINIT_APARTMENTTHREADED | ::COINIT_DISABLE_OLE1DDE
@ -386,10 +452,13 @@ static nfdresult_t SetDefaultPath( IFileDialog *dialog, const char *defaultPath
nfdresult_t NFD_OpenDialog( const nfdchar_t *filterList,
const nfdchar_t *defaultPath,
nfdchar_t **outPath )
nfdchar_t **outPath,
nfdselcallback_t selCallback )
{
nfdresult_t nfdResult = NFD_ERROR;
NFDWinEvents* winEvents;
bool hasEvents=true;
DWORD eventID=0;
HRESULT coResult = COMInit();
if (!COMIsInitialized(coResult))
@ -420,7 +489,17 @@ nfdresult_t NFD_OpenDialog( const nfdchar_t *filterList,
if ( !SetDefaultPath( fileOpenDialog, defaultPath ) )
{
goto end;
}
}
// Pass the callback
winEvents=new NFDWinEvents(selCallback);
if ( !SUCCEEDED(fileOpenDialog->Advise(winEvents,&eventID)) ) {
// error... ignore
hasEvents=false;
winEvents->Release();
} else {
winEvents->Release();
}
// Show the dialog.
// TODO: pass the Furnace window here
@ -467,8 +546,12 @@ nfdresult_t NFD_OpenDialog( const nfdchar_t *filterList,
}
end:
if (fileOpenDialog)
if (fileOpenDialog) {
if (hasEvents) {
fileOpenDialog->Unadvise(eventID);
}
fileOpenDialog->Release();
}
COMUninit(coResult);
@ -477,7 +560,8 @@ end:
nfdresult_t NFD_OpenDialogMultiple( const nfdchar_t *filterList,
const nfdchar_t *defaultPath,
nfdpathset_t *outPaths )
nfdpathset_t *outPaths,
nfdselcallback_t selCallback )
{
nfdresult_t nfdResult = NFD_ERROR;
@ -571,7 +655,8 @@ end:
nfdresult_t NFD_SaveDialog( const nfdchar_t *filterList,
const nfdchar_t *defaultPath,
nfdchar_t **outPath )
nfdchar_t **outPath,
nfdselcallback_t selCallback )
{
nfdresult_t nfdResult = NFD_ERROR;

View File

@ -30,9 +30,9 @@ void _nfdThread(const NFDState state, std::atomic<bool>* ok, String* result) {
nfdresult_t ret=NFD_CANCEL;
if (state.isSave) {
ret=NFD_SaveDialog(NULL,state.path.c_str(),&out);
ret=NFD_SaveDialog(NULL,state.path.c_str(),&out,state.clickCallback);
} else {
ret=NFD_OpenDialog(NULL,state.path.c_str(),&out);
ret=NFD_OpenDialog(NULL,state.path.c_str(),&out,state.clickCallback);
}
switch (ret) {