From 4daf959f15f55ffa548d72245946315cff3ed845 Mon Sep 17 00:00:00 2001 From: tildearrow Date: Fri, 2 Dec 2022 18:16:41 -0500 Subject: [PATCH] GUI: mobile file dialog improvements, part 2 --- .../org/tildearrow/furnace/MainActivity.java | 14 ++++- src/gui/fileDialog.cpp | 54 ++++++++++++++++++- 2 files changed, 66 insertions(+), 2 deletions(-) diff --git a/android/app/src/main/java/org/tildearrow/furnace/MainActivity.java b/android/app/src/main/java/org/tildearrow/furnace/MainActivity.java index f1bc8bfd4..01b584202 100644 --- a/android/app/src/main/java/org/tildearrow/furnace/MainActivity.java +++ b/android/app/src/main/java/org/tildearrow/furnace/MainActivity.java @@ -2,12 +2,14 @@ package org.tildearrow.furnace; import android.content.Context; import android.content.Intent; +import android.net.Uri; import android.widget.Toast; import org.libsdl.app.SDLActivity; public class MainActivity extends SDLActivity { static final int TA_FILE_REQUEST=1000; + static final int TA_FILE_SAVE_REQUEST=1001; public void showFileDialog() { Intent picker=new Intent(Intent.ACTION_GET_CONTENT); @@ -16,12 +18,22 @@ public class MainActivity extends SDLActivity { startActivityForResult(picker,TA_FILE_REQUEST); } + public void showSaveFileDialog() { + Intent picker=new Intent(Intent.ACTION_CREATE_DOCUMENT); + picker.addCategory(Intent.CATEGORY_OPENABLE); + picker.setType("*/*"); + + startActivityForResult(picker,TA_FILE_SAVE_REQUEST); + } + @Override protected void onActivityResult(int request, int result, Intent intent) { super.onActivityResult(request,result,intent); if (request==TA_FILE_REQUEST) { if (result==RESULT_OK) { + Uri path=intent.getData(); + Context context=getApplicationContext(); - Toast toast=Toast.makeText(context,"Got a file",Toast.LENGTH_SHORT); + Toast toast=Toast.makeText(context,path.toString(),Toast.LENGTH_SHORT); toast.show(); } } diff --git a/src/gui/fileDialog.cpp b/src/gui/fileDialog.cpp index 3c913d74a..4eb00bc73 100644 --- a/src/gui/fileDialog.cpp +++ b/src/gui/fileDialog.cpp @@ -142,6 +142,13 @@ bool FurnaceGUIFileDialog::openLoad(String header, std::vector filter, c #endif } else { hasError=false; + +#ifdef ANDROID + if (!SDL_AndroidRequestPermission("android.permission.READ_EXTERNAL_STORAGE")) { + return false; + } +#endif + ImGuiFileDialog::Instance()->singleClickSel=singleClickSel; ImGuiFileDialog::Instance()->DpiScale=dpiScale; ImGuiFileDialog::Instance()->OpenModal("FileDialog",header,noSysFilter,path,allowMultiple?999:1,nullptr,0,clickCallback); @@ -152,6 +159,13 @@ bool FurnaceGUIFileDialog::openLoad(String header, std::vector filter, c bool FurnaceGUIFileDialog::openSave(String header, std::vector filter, const char* noSysFilter, String path, double dpiScale) { if (opened) return false; + +#ifdef ANDROID + if (!SDL_AndroidRequestPermission("android.permission.WRITE_EXTERNAL_STORAGE")) { + return false; + } +#endif + saving=true; curPath=path; @@ -172,13 +186,51 @@ bool FurnaceGUIFileDialog::openSave(String header, std::vector filter, c dialogS=new std::thread(_nfdThread,NFDState(true,header,filter,path,NULL,false),&dialogOK,&nfdResult,&hasError); #endif #elif defined(ANDROID) - hasError=true; // TODO + hasError=false; + if (jniEnv==NULL) { + jniEnv=(JNIEnv*)SDL_AndroidGetJNIEnv(); + if (jniEnv==NULL) { + hasError=true; + logE("could not acquire JNI env!"); + return false; + } + } + + jobject activity=(jobject)SDL_AndroidGetActivity(); + if (activity==NULL) { + hasError=true; + logE("the Activity is NULL!"); + return false; + } + + jclass class_=jniEnv->GetObjectClass(activity); + jmethodID showSaveFileDialog=jniEnv->GetMethodID(class_,"showSaveFileDialog","()V"); + + if (showSaveFileDialog==NULL) { + logE("method showSaveFileDialog not found!"); + hasError=true; + jniEnv->DeleteLocalRef(class_); + jniEnv->DeleteLocalRef(activity); + return false; + } + + jniEnv->CallVoidMethod(activity,showSaveFileDialog); + + /*if (!(bool)mret) { + hasError=true; + logW("could not open Android file picker..."); + }*/ + + jniEnv->DeleteLocalRef(class_); + jniEnv->DeleteLocalRef(activity); + return true; #else dialogS=new pfd::save_file(header,path,filter); hasError=!pfd::settings::available(); #endif } else { hasError=false; + ImGuiFileDialog::Instance()->singleClickSel=false; ImGuiFileDialog::Instance()->DpiScale=dpiScale; ImGuiFileDialog::Instance()->OpenModal("FileDialog",header,noSysFilter,path,1,nullptr,ImGuiFileDialogFlags_ConfirmOverwrite);