diff --git a/android/android/CMakeLists.txt b/android/android/CMakeLists.txt index 16261f8..ccd1b9e 100644 --- a/android/android/CMakeLists.txt +++ b/android/android/CMakeLists.txt @@ -111,6 +111,8 @@ add_library( ../../src/binary_stream.cpp ../../src/serializer.cpp ../../src/settings.cpp + ../../src/node_input_box.cpp + ../../src/node_dialog_export_ppbr.cpp ) target_include_directories(native-lib PRIVATE diff --git a/android/src/cpp/main.cpp b/android/src/cpp/main.cpp index 8233bf8..b8ab7b7 100644 --- a/android/src/cpp/main.cpp +++ b/android/src/cpp/main.cpp @@ -296,6 +296,14 @@ void android_pick_file(std::function callback) jni->CallVoidMethod(g_engine.app->activity->clazz, method); } +void android_pick_file_save(std::function callback) +{ + pick_file_callback = callback; + jclass clazz = jni->GetObjectClass(g_engine.app->activity->clazz); + jmethodID method = jni->GetMethodID(clazz, "pickFileSave", "()V"); + jni->CallVoidMethod(g_engine.app->activity->clazz, method); +} + float get_display_density() { jclass clazz = jni->GetObjectClass(g_engine.app->activity->clazz); @@ -366,6 +374,17 @@ bool android_set_clipboard(const std::string& s) return success; } +bool android_create_dir(const std::string& path) +{ + jclass clazz = jni->GetObjectClass(g_engine.app->activity->clazz); + jmethodID method = jni->GetMethodID(clazz, "createDir", "(Ljava/lang/String;)Z"); + jstring js = JniStringFromUTF8(path); + if (!js) return false; + jboolean success = jni->CallBooleanMethod(g_engine.app->activity->clazz, method, js); + jni->DeleteLocalRef(js); + return success; +} + bool vr_running = false; static void engine_vr_loop() { @@ -1029,12 +1048,12 @@ static void engine_handle_cmd(struct android_app* app, int32_t cmd) { break; case APP_CMD_WINDOW_REDRAW_NEEDED: LOG("APP_CMD_WINDOW_REDRAW_NEEDED"); - App::I->redraw = true; + App::I->ui_task([]{ App::I->update(0); }); ALooper_wake(engine->app->looper); break; case APP_CMD_WINDOW_RESIZED: LOG("APP_CMD_WINDOW_RESIZED"); - App::I->redraw = true; + App::I->async_redraw(); ALooper_wake(engine->app->looper); break; case APP_CMD_CONTENT_RECT_CHANGED: @@ -1042,7 +1061,7 @@ static void engine_handle_cmd(struct android_app* app, int32_t cmd) { //App::I->width = engine->app->contentRect.right - engine->app->contentRect.left; //App::I->height = engine->app->contentRect.bottom - engine->app->contentRect.top; //LOG("content rect %f %f", App::I->width, App::I->height); - App::I->redraw = true; + App::I->async_redraw(); ALooper_wake(engine->app->looper); break; } diff --git a/android/src/cpp/native-lib.cpp b/android/src/cpp/native-lib.cpp deleted file mode 100644 index d8b919a..0000000 --- a/android/src/cpp/native-lib.cpp +++ /dev/null @@ -1,7 +0,0 @@ -#include - -int main() -{ - return 0; -} - diff --git a/android/src/java/com/omixlab/panopainter/MainActivity.java b/android/src/java/com/omixlab/panopainter/MainActivity.java index ad80763..f964176 100644 --- a/android/src/java/com/omixlab/panopainter/MainActivity.java +++ b/android/src/java/com/omixlab/panopainter/MainActivity.java @@ -54,6 +54,23 @@ public class MainActivity extends PlatformActivity { public native void pickExternalCallback(String path); public native void contentRectChanged(int wnd_w, int wnd_h, int rect_left, int rect_top, int rect_right, int rect_bottom); + public boolean createDir(String path) + { + File dir = new File(path); + + if (!dir.exists()) + { + boolean success = dir.mkdirs(); + if (success) + Log.v("PanoPainterJava", "create path " + dir.getAbsolutePath()); + else + Log.v("PanoPainterJava", "create path failed " + dir.getAbsolutePath()); + return success; + } + Log.v("PanoPainterJava", "create path already existed " + dir.getAbsolutePath()); + return true; + } + public void setRootPath() { Log.v("PanoPainterJava", "permission granted"); @@ -225,13 +242,22 @@ public class MainActivity extends PlatformActivity { public void pickFile() { - Intent intent = new Intent(Intent.ACTION_GET_CONTENT); + Intent intent = new Intent(Intent.ACTION_OPEN_DOCUMENT); intent.addCategory(Intent.CATEGORY_OPENABLE); intent.setType("*/*"); startActivityForResult(Intent.createChooser(intent, "Select a file"), 1); Log.v("PanoPainterJava", "pick start"); } + public void pickFileSave() + { + Intent intent = new Intent(Intent.ACTION_CREATE_DOCUMENT); + intent.addCategory(Intent.CATEGORY_OPENABLE); + intent.setType("*/*"); + startActivityForResult(Intent.createChooser(intent, "Select a file"), 1); + Log.v("PanoPainterJava", "pick save start"); + } + @Override protected void onActivityResult(int requestCode, int resultCode, Intent data) { super.onActivityResult(requestCode, resultCode, data); diff --git a/src/app_events.cpp b/src/app_events.cpp index 5a97174..a900664 100644 --- a/src/app_events.cpp +++ b/src/app_events.cpp @@ -4,6 +4,7 @@ #ifdef __ANDROID__ void displayKeyboard(bool pShow); void android_pick_file(std::function callback); +void android_pick_file_save(std::function callback); std::string android_get_clipboard(); bool android_set_clipboard(const std::string& s); #elif _WIN32 @@ -228,7 +229,7 @@ void App::pick_file_save(std::vector types, std::function AAssetManager* Asset::m_am; +bool android_create_dir(const std::string& path); #endif bool Asset::delete_file(const std::string& path) @@ -134,6 +135,15 @@ bool Asset::is_asset(const std::string & path) return path.substr(0, 5) == "data/"; } +bool Asset::create_dir(const std::string& path) +{ +#if __WIN__ + return PathFileExistsA(path.c_str()) ? true : CreateDirectoryA(path.c_str(), NULL); +#elif __ANDROID__ + return android_create_dir(path); +#endif +} + bool Asset::open(const char* path) { //LOG("Asset::open %s", path); diff --git a/src/asset.h b/src/asset.h index c4371f3..30aa6b0 100644 --- a/src/asset.h +++ b/src/asset.h @@ -12,6 +12,7 @@ public: static bool delete_file(const std::string& path); static std::string absolute(const std::string& path); static bool is_asset(const std::string& path); + static bool create_dir(const std::string& path); std::string m_current_path; FILE* m_fp = nullptr; int m_len = 0;