-
Notifications
You must be signed in to change notification settings - Fork 199
SDL3 File Dialogs #960
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
SDL3 File Dialogs #960
Changes from 5 commits
6f1985c
6f62362
039c635
969c4ea
09ac4c2
c1fe5a6
e045296
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -1156,3 +1156,106 @@ DEFINE_PRIM(_ARR, get_display_modes, _I32); | |
| DEFINE_PRIM(_DYN, get_current_display_mode, _I32 _BOOL); | ||
| DEFINE_PRIM(_ARR, get_devices, _NO_ARG); | ||
| DEFINE_PRIM(_BYTES, get_error, _NO_ARG); | ||
|
|
||
| // SDL Dialogs API | ||
| typedef struct { | ||
| vclosure **closure_store; | ||
| SDL_DialogFileFilter* filters; | ||
| } dialog_data; | ||
|
|
||
| dialog_data* CreateFileDialogData( vclosure *callback, varray *filters ) { | ||
| dialog_data *data = malloc( sizeof( dialog_data ) ); | ||
| data->closure_store = malloc(sizeof(vclosure*)); | ||
| *data->closure_store = callback; | ||
|
|
||
| if( filters && filters->size > 0 ) { | ||
| SDL_DialogFileFilter *sdl_filters = (SDL_DialogFileFilter *)malloc(sizeof( SDL_DialogFileFilter ) * filters->size ); | ||
|
|
||
| for(int i=0;i<filters->size;i++) { | ||
| vdynamic *filter = hl_aptr(filters, vdynamic*)[i]; | ||
| const char *name = (const char*) hl_dyn_getp(filter,hl_hash_utf8("name"),&hlt_bytes); | ||
| const char *pattern = (const char*) hl_dyn_getp(filter,hl_hash_utf8("pattern"),&hlt_bytes); | ||
|
|
||
| sdl_filters[i].name = name; | ||
| sdl_filters[i].pattern = pattern; | ||
| } | ||
|
|
||
| data->filters = sdl_filters; | ||
| } | ||
| else | ||
| data->filters = NULL; | ||
|
|
||
| hl_add_root(data->closure_store); | ||
|
|
||
| return data; | ||
| } | ||
|
|
||
| void FileDialogCallback(void *userdata, const char* const *filelist, int filter) { | ||
| // these callbacks may come via threads on some platforms | ||
| bool on_unregistered_thread = !hl_get_thread(); | ||
| if( on_unregistered_thread ) { | ||
| vdynamic *ctx; | ||
| hl_register_thread(&ctx); | ||
| } | ||
|
|
||
| dialog_data *data = (dialog_data*)userdata; | ||
| vclosure *vcallback = *data->closure_store; | ||
|
|
||
| int count = 0; | ||
|
|
||
| varray *array; | ||
| if( filelist ) { | ||
| const char * const *p = filelist; | ||
| while(*p++) | ||
| count++; | ||
|
|
||
| array = hl_alloc_array(&hlt_bytes, count ); | ||
| vbyte **array_ptr = (vbyte **)hl_aptr(array, vbyte*); | ||
|
|
||
| for(int i = 0; i < count; i++) { | ||
| size_t len = strlen(filelist[i]) + 1; // Include the null terminator | ||
| vbyte *bytes = hl_alloc_bytes( len ); | ||
| memcpy(bytes, filelist[i], len); | ||
| array_ptr[i] = bytes; | ||
| } | ||
| } else { | ||
| array = hl_alloc_array(&hlt_bytes, 0 ); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. When I'm trying to call with a filter on Windows, it return immediatly an empty array without open any window (works normally if no filters specifield). From C side I saw that
I think it would be good if we can at least give some information to the haxe side about the error, instead of returning empty list here (return NULL or throw?). sdl.Sdl.showOpenFileDialog(function(arr) {
trace("Open " + arr);
}, null, [{ name : "hxml", pattern : "*.hxml" }]
);
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This one's kinda tricky since we can't validate filters before the callback (the SDL internal What I've done is to pass the NULL state into haxe, and
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think it's only about filters, errors can come from elsewhere, so it's good that at least we return NULL from C side. |
||
| } | ||
|
|
||
| hl_call1( void, vcallback, varray*, array ); | ||
| hl_remove_root( data->closure_store ); | ||
| free( data->closure_store ); | ||
| free( data->filters ); | ||
| free( data ); | ||
|
|
||
| if( on_unregistered_thread ) | ||
| hl_unregister_thread(); | ||
| } | ||
|
|
||
| HL_PRIM void HL_NAME(show_open_file_dialog)( vclosure *callback, SDL_Window *window, varray *filters, vstring *default_location, bool allow_many ) { | ||
| const char *location = default_location ? hl_to_utf8(default_location->bytes) : NULL; | ||
|
|
||
| dialog_data *data = CreateFileDialogData( callback, filters ); | ||
|
|
||
| SDL_ShowOpenFileDialog( FileDialogCallback, data, window, data->filters, filters ? filters->size : 0, location, allow_many ); | ||
| } | ||
|
|
||
| HL_PRIM void HL_NAME(show_open_folder_dialog)( vclosure *callback, SDL_Window *window, vstring *default_location, bool allow_many ) { | ||
| const char *location = default_location ? hl_to_utf8(default_location->bytes) : NULL; | ||
|
|
||
| dialog_data *data = CreateFileDialogData( callback, NULL ); | ||
|
|
||
| SDL_ShowOpenFolderDialog( FileDialogCallback, data, window, location, allow_many ); | ||
| } | ||
|
|
||
| HL_PRIM void HL_NAME(show_save_file_dialog)( vclosure *callback, SDL_Window *window, varray *filters, vstring *default_location ) { | ||
| const char *location = default_location ? hl_to_utf8(default_location->bytes) : NULL; | ||
|
|
||
| dialog_data *data = CreateFileDialogData( callback, filters ); | ||
|
|
||
| SDL_ShowSaveFileDialog( FileDialogCallback, data, window, data->filters, filters ? filters->size : 0, location ); | ||
| } | ||
|
|
||
| DEFINE_PRIM(_VOID, show_open_file_dialog, _FUN(_VOID, _ARR) TWIN _ARR _STRING _BOOL ); | ||
| DEFINE_PRIM(_VOID, show_open_folder_dialog, _FUN(_VOID, _ARR) TWIN _STRING _BOOL ); | ||
| DEFINE_PRIM(_VOID, show_save_file_dialog, _FUN(_VOID, _ARR) TWIN _ARR _STRING ); | ||
Uh oh!
There was an error while loading. Please reload this page.