Android: Add support for folder dialogs

This commit is contained in:
crudelios
2026-05-13 17:50:42 +01:00
committed by Sam Lantinga
parent de08751537
commit 439ffd13eb
5 changed files with 138 additions and 52 deletions

View File

@@ -688,7 +688,7 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(nativeSetupJNI)(JNIEnv *env, jclass cl
midShowTextInput = (*env)->GetStaticMethodID(env, mActivityClass, "showTextInput", "(IIIII)Z");
midSupportsRelativeMouse = (*env)->GetStaticMethodID(env, mActivityClass, "supportsRelativeMouse", "()Z");
midOpenFileDescriptor = (*env)->GetStaticMethodID(env, mActivityClass, "openFileDescriptor", "(Ljava/lang/String;Ljava/lang/String;)I");
midShowFileDialog = (*env)->GetStaticMethodID(env, mActivityClass, "showFileDialog", "([Ljava/lang/String;ZZI)Z");
midShowFileDialog = (*env)->GetStaticMethodID(env, mActivityClass, "showFileDialog", "([Ljava/lang/String;ZILjava/lang/String;I)Z");
midGetPreferredLocales = (*env)->GetStaticMethodID(env, mActivityClass, "getPreferredLocales", "()Ljava/lang/String;");
if (!midClipboardGetText ||
@@ -3386,18 +3386,34 @@ JNIEXPORT void JNICALL SDL_JAVA_INTERFACE(onNativeFileDialog)(
}
}
bool Android_JNI_OpenFileDialog(
bool Android_JNI_ShowFileDialog(
SDL_DialogFileCallback callback, void *userdata,
const SDL_DialogFileFilter *filters, int nfilters, bool forwrite,
bool multiple)
const SDL_DialogFileFilter *filters, int nfilters, SDL_FileDialogType type,
bool multiple, const char *initialPath)
{
if (mAndroidFileDialogData.callback != NULL) {
SDL_SetError("Only one file dialog can be run at a time.");
return false;
}
if (forwrite) {
// Setup type
int dialogType = 0;
switch (type) {
case SDL_FILEDIALOG_OPENFILE:
dialogType = 0;
break;
case SDL_FILEDIALOG_SAVEFILE:
multiple = false;
dialogType = 1;
break;
case SDL_FILEDIALOG_OPENFOLDER:
multiple = false;
dialogType = 2;
break;
default:
SDL_SetError("Invalid file dialog type");
return false;
}
JNIEnv *env = Android_JNI_GetEnv();
@@ -3417,6 +3433,12 @@ bool Android_JNI_OpenFileDialog(
}
}
// Setup initial path
jstring initialPathString = NULL;
if (initialPath && *initialPath) {
initialPathString = (*env)->NewStringUTF(env, initialPath);
}
// Setup data
static SDL_AtomicInt next_request_code;
mAndroidFileDialogData.request_code = SDL_AddAtomicInt(&next_request_code, 1);
@@ -3425,8 +3447,10 @@ bool Android_JNI_OpenFileDialog(
// Invoke JNI
jboolean success = (*env)->CallStaticBooleanMethod(env, mActivityClass,
midShowFileDialog, filtersArray, (jboolean) multiple, (jboolean) forwrite, mAndroidFileDialogData.request_code);
midShowFileDialog, filtersArray, (jboolean) multiple,
dialogType, initialPathString, mAndroidFileDialogData.request_code);
(*env)->DeleteLocalRef(env, filtersArray);
(*env)->DeleteLocalRef(env, initialPathString);
if (!success) {
mAndroidFileDialogData.callback = NULL;
SDL_AddAtomicInt(&next_request_code, -1);

View File

@@ -154,9 +154,9 @@ bool SDL_IsAndroidTablet(void);
bool SDL_IsAndroidTV(void);
// File Dialogs
bool Android_JNI_OpenFileDialog(SDL_DialogFileCallback callback, void *userdata,
const SDL_DialogFileFilter *filters, int nfilters, bool forwrite,
bool multiple);
bool Android_JNI_ShowFileDialog(SDL_DialogFileCallback callback, void *userdata,
const SDL_DialogFileFilter *filters, int nfilters, SDL_FileDialogType type,
bool multiple, const char *initialPath);
// Ends C function definitions when using C++
#ifdef __cplusplus

View File

@@ -28,7 +28,7 @@ void SDL_SYS_ShowFileDialogWithProperties(SDL_FileDialogType type, SDL_DialogFil
SDL_DialogFileFilter *filters = SDL_GetPointerProperty(props, SDL_PROP_FILE_DIALOG_FILTERS_POINTER, NULL);
int nfilters = (int) SDL_GetNumberProperty(props, SDL_PROP_FILE_DIALOG_NFILTERS_NUMBER, 0);
bool allow_many = SDL_GetBooleanProperty(props, SDL_PROP_FILE_DIALOG_MANY_BOOLEAN, false);
bool is_save;
const char *base_folder = SDL_GetStringProperty(props, SDL_PROP_FILE_DIALOG_LOCATION_STRING, NULL);
if (SDL_GetHint(SDL_HINT_FILE_DIALOG_DRIVER) != NULL) {
SDL_SetError("File dialog driver unsupported (don't set SDL_HINT_FILE_DIALOG_DRIVER)");
@@ -36,22 +36,7 @@ void SDL_SYS_ShowFileDialogWithProperties(SDL_FileDialogType type, SDL_DialogFil
return;
}
switch (type) {
case SDL_FILEDIALOG_OPENFILE:
is_save = false;
break;
case SDL_FILEDIALOG_SAVEFILE:
is_save = true;
break;
case SDL_FILEDIALOG_OPENFOLDER:
SDL_Unsupported();
callback(userdata, NULL, -1);
return;
}
if (!Android_JNI_OpenFileDialog(callback, userdata, filters, nfilters, is_save, allow_many)) {
if (!Android_JNI_ShowFileDialog(callback, userdata, filters, nfilters, type, allow_many, base_folder)) {
// SDL_SetError is already called when it fails
callback(userdata, NULL, -1);
}