From 7f94f65bea8cfecf74e5a1ae5ee366c0dcb541ca Mon Sep 17 00:00:00 2001 From: Yousef Khadadeh Date: Sun, 31 May 2026 18:35:57 +0300 Subject: [PATCH] Added share buttons to android --- android-project/app/build.gradle | 1 + android-project/app/proguard-rules.pro | 2 + .../app/src/main/AndroidManifest.xml | 10 ++++ .../erroratline0/infinipaint/InfiniPaint.java | 34 +++++++++++++ .../infinipaint/InfiniPaintFileProvider.java | 9 ++++ .../app/src/main/res/xml/file_paths.xml | 5 ++ android-project/build.gradle | 2 +- android-project/gradle.properties | 1 + .../gradle/wrapper/gradle-wrapper.properties | 2 +- assets/data/icons/RemixIcon/share-line.svg | 1 + src/AndroidJNICalls.cpp | 22 +++++++++ src/AndroidJNICalls.hpp | 2 + src/DrawingProgram/Tools/BrushTool.cpp | 4 -- src/Screens/FileSelectScreen.cpp | 20 ++++++++ src/Screens/FileSelectScreen.hpp | 1 + src/Screens/PhoneDrawingProgramScreen.cpp | 49 ++++++++++++++----- 16 files changed, 146 insertions(+), 19 deletions(-) create mode 100644 android-project/app/src/main/java/com/erroratline0/infinipaint/InfiniPaintFileProvider.java create mode 100644 android-project/app/src/main/res/xml/file_paths.xml create mode 100644 assets/data/icons/RemixIcon/share-line.svg diff --git a/android-project/app/build.gradle b/android-project/app/build.gradle index be0dc39..59e4de1 100644 --- a/android-project/app/build.gradle +++ b/android-project/app/build.gradle @@ -96,4 +96,5 @@ android { dependencies { implementation fileTree(include: ['*.jar'], dir: 'libs') + implementation "androidx.core:core:1.18.0" } diff --git a/android-project/app/proguard-rules.pro b/android-project/app/proguard-rules.pro index 6fac289..db60cc6 100644 --- a/android-project/app/proguard-rules.pro +++ b/android-project/app/proguard-rules.pro @@ -22,6 +22,8 @@ void updateTextboxAndCursorPos(java.lang.String, int, int); void startNetworkService(); void stopNetworkService(); + void shareText(java.lang.String); + void shareInternalFile(java.lang.String, java.lang.String); } -keep,includedescriptorclasses,allowoptimization class org.libsdl.app.SDLActivity { diff --git a/android-project/app/src/main/AndroidManifest.xml b/android-project/app/src/main/AndroidManifest.xml index 7a0e539..c98589a 100644 --- a/android-project/app/src/main/AndroidManifest.xml +++ b/android-project/app/src/main/AndroidManifest.xml @@ -89,6 +89,16 @@ android:value="When connected to a server/hosting a server, keep the connection alive even when the application is in the background."/> + + + + + + + + \ No newline at end of file diff --git a/android-project/build.gradle b/android-project/build.gradle index ed2299c..902fed6 100644 --- a/android-project/build.gradle +++ b/android-project/build.gradle @@ -6,7 +6,7 @@ buildscript { google() } dependencies { - classpath 'com.android.tools.build:gradle:8.7.3' + classpath 'com.android.tools.build:gradle:8.13.2' // NOTE: Do not place your application dependencies here; they belong // in the individual module build.gradle files diff --git a/android-project/gradle.properties b/android-project/gradle.properties index aac7c9b..6dd0218 100644 --- a/android-project/gradle.properties +++ b/android-project/gradle.properties @@ -10,6 +10,7 @@ # Specifies the JVM arguments used for the daemon process. # The setting is particularly useful for tweaking memory settings. org.gradle.jvmargs=-Xmx1536m +android.useAndroidX=true # When configured, Gradle will run in incubating parallel mode. # This option should only be used with decoupled projects. More details, visit diff --git a/android-project/gradle/wrapper/gradle-wrapper.properties b/android-project/gradle/wrapper/gradle-wrapper.properties index 99fbfa0..ec50cfc 100644 --- a/android-project/gradle/wrapper/gradle-wrapper.properties +++ b/android-project/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ #Thu Nov 11 18:20:34 PST 2021 distributionBase=GRADLE_USER_HOME -distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.13-bin.zip distributionPath=wrapper/dists zipStorePath=wrapper/dists zipStoreBase=GRADLE_USER_HOME diff --git a/assets/data/icons/RemixIcon/share-line.svg b/assets/data/icons/RemixIcon/share-line.svg new file mode 100644 index 0000000..8ff03d3 --- /dev/null +++ b/assets/data/icons/RemixIcon/share-line.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/AndroidJNICalls.cpp b/src/AndroidJNICalls.cpp index 4a17666..eeb3858 100644 --- a/src/AndroidJNICalls.cpp +++ b/src/AndroidJNICalls.cpp @@ -58,6 +58,28 @@ namespace AndroidJNICalls { bool textChanged = false; bool cursorChanged = false; + void shareInternalFile(const std::string& filePath, const std::string& mimeType) { + Logger::get().log(Logger::LogType::INFO, "[AndroidJNICalls::shareInternalFile] Share internal file " + filePath); + JNIEnv* env = static_cast(SDL_GetAndroidJNIEnv()); + jobject activity = (jobject)SDL_GetAndroidActivity(); + jclass clazz = env->GetObjectClass(activity); + jmethodID method_id = env->GetStaticMethodID(clazz, "shareInternalFile", "(Ljava/lang/String;Ljava/lang/String;)V"); + env->CallStaticVoidMethod(clazz, method_id, string2jstring(env, filePath), string2jstring(env, mimeType)); + env->DeleteLocalRef(activity); + env->DeleteLocalRef(clazz); + } + + void shareText(const std::string& str) { + Logger::get().log(Logger::LogType::INFO, "[AndroidJNICalls::shareText] Share text " + str); + JNIEnv* env = static_cast(SDL_GetAndroidJNIEnv()); + jobject activity = (jobject)SDL_GetAndroidActivity(); + jclass clazz = env->GetObjectClass(activity); + jmethodID method_id = env->GetStaticMethodID(clazz, "shareText", "(Ljava/lang/String;)V"); + env->CallStaticVoidMethod(clazz, method_id, string2jstring(env, str)); + env->DeleteLocalRef(activity); + env->DeleteLocalRef(clazz); + } + int get_android_text_pos_from_cursor_pos(const std::shared_ptr& t, const RichText::TextPosition& p) { return t->get_utf16_location_from_codepoint_location(t->get_codepoint_location_from_text_position(p)); } diff --git a/src/AndroidJNICalls.hpp b/src/AndroidJNICalls.hpp index e947866..f0170c2 100644 --- a/src/AndroidJNICalls.hpp +++ b/src/AndroidJNICalls.hpp @@ -26,6 +26,8 @@ struct InputManager; namespace AndroidJNICalls { extern InputManager* globalInputManager; + void shareInternalFile(const std::string& filePath, const std::string& mimeType); + void shareText(const std::string& str); void startTextInput(CustomEvents::InputTextBoxID newTextboxID, const std::shared_ptr& newTextbox, const std::shared_ptr& newCursor, const std::shared_ptr& modMap, int inputType); void startNetworkService(); void stopNetworkService(); diff --git a/src/DrawingProgram/Tools/BrushTool.cpp b/src/DrawingProgram/Tools/BrushTool.cpp index 50ca56d..e4c0a2a 100644 --- a/src/DrawingProgram/Tools/BrushTool.cpp +++ b/src/DrawingProgram/Tools/BrushTool.cpp @@ -29,10 +29,6 @@ #include "../../GUIStuff/ElementHelpers/CheckBoxHelpers.hpp" #include -#define MINIMUM_DISTANCE_FROM_FIRST_POINT 3.0f -#define MINIMUM_DISTANCE_TO_NEXT_POINT 0.002f -#define DRAW_MINIMUM_LIMIT 1.0f - BrushTool::BrushTool(DrawingProgram& initDrawP): DrawingProgramToolBase(initDrawP) {} diff --git a/src/Screens/FileSelectScreen.cpp b/src/Screens/FileSelectScreen.cpp index d4d5def..d8b1068 100644 --- a/src/Screens/FileSelectScreen.cpp +++ b/src/Screens/FileSelectScreen.cpp @@ -427,6 +427,17 @@ void FileSelectScreen::move_selected_files(const std::filesystem::path& fromPath } } +void FileSelectScreen::share_selected_files() { + for(const FileInfo& f : fileList) { + if(f.selected) { +#ifdef __ANDROID__ + AndroidJNICalls::shareInternalFile("saves/" + f.fileName + ".infpnt", "application/octet-stream"); +#endif + break; + } + } +} + void FileSelectScreen::duplicate_selected_files(const std::filesystem::path& inPath) { std::vector toFolderListNames; try { @@ -571,6 +582,15 @@ void FileSelectScreen::edit_action_bar() { update_file_list(fileList, savePath, false); editMode = false; }); +#ifdef __ANDROID__ + if(numberOfSelectedEntries == 1) { + edit_action_bar_button("share", "data/icons/RemixIcon/share-line.svg", "Share", [&] { + share_selected_files(); + update_file_list(fileList, savePath, false); + editMode = false; + }); + } +#endif } else if(selectedMenu == SelectedMenu::TRASH) { edit_action_bar_button("restore", "data/icons/RemixIcon/refresh-line.svg", "Restore", [&] { diff --git a/src/Screens/FileSelectScreen.hpp b/src/Screens/FileSelectScreen.hpp index a2f5812..44dfdaf 100644 --- a/src/Screens/FileSelectScreen.hpp +++ b/src/Screens/FileSelectScreen.hpp @@ -112,6 +112,7 @@ class FileSelectScreen : public Screen { }; void move_selected_files(const std::filesystem::path& fromPath, const std::filesystem::path& toPath, TrashMoveType trashMoveType); void duplicate_selected_files(const std::filesystem::path& inPath); + void share_selected_files(); void delete_selected_files_in_trash(); enum class MoreOptionsMenu { diff --git a/src/Screens/PhoneDrawingProgramScreen.cpp b/src/Screens/PhoneDrawingProgramScreen.cpp index ed5641b..67cf7b8 100644 --- a/src/Screens/PhoneDrawingProgramScreen.cpp +++ b/src/Screens/PhoneDrawingProgramScreen.cpp @@ -255,13 +255,25 @@ void PhoneDrawingProgramScreen::top_toolbar_settings_popup() { input_text_field(gui, "lobby", "Lobby", &serverToConnectTo, { .immutable = true }); - text_button(gui, "Host button", "Copy & Host", { - .wide = true, - .onClick = [&] { - main.input.set_clipboard_str(serverToConnectTo); - main.world->start_hosting(serverToConnectTo, serverLocalID); - topToolbarSettingsPopup = TopToolbarSettingsPopup::NONE; - } + left_to_right_line_layout(gui, [&] { + text_button(gui, "Host button", "Copy & Host", { + .wide = true, + .onClick = [&] { + main.input.set_clipboard_str(serverToConnectTo); + main.world->start_hosting(serverToConnectTo, serverLocalID); + topToolbarSettingsPopup = TopToolbarSettingsPopup::NONE; + } + }); +#ifdef __ANDROID__ + text_button(gui, "Share and host button", "Share & Host", { + .wide = true, + .onClick = [&] { + AndroidJNICalls::shareText(serverToConnectTo); + main.world->start_hosting(serverToConnectTo, serverLocalID); + topToolbarSettingsPopup = TopToolbarSettingsPopup::NONE; + } + }); +#endif }); } }); @@ -291,12 +303,23 @@ void PhoneDrawingProgramScreen::top_toolbar_settings_popup() { input_text_field(gui, "lobby", "Lobby", &serverToConnectTo, { .immutable = true }); - text_button(gui, "Copy button", "Copy", { - .wide = true, - .onClick = [&] { - main.input.set_clipboard_str(serverToConnectTo); - topToolbarSettingsPopup = TopToolbarSettingsPopup::NONE; - } + left_to_right_line_layout(gui, [&] { + text_button(gui, "Copy button", "Copy", { + .wide = true, + .onClick = [&] { + main.input.set_clipboard_str(serverToConnectTo); + topToolbarSettingsPopup = TopToolbarSettingsPopup::NONE; + } + }); +#ifdef __ANDROID__ + text_button(gui, "Share button", "Share", { + .wide = true, + .onClick = [&] { + AndroidJNICalls::shareText(serverToConnectTo); + topToolbarSettingsPopup = TopToolbarSettingsPopup::NONE; + } + }); +#endif }); } });