diff --git a/android-project/app/src/main/java/com/erroratline0/infinipaint/InfiniPaint.java b/android-project/app/src/main/java/com/erroratline0/infinipaint/InfiniPaint.java index ebe7e8c..32ac711 100644 --- a/android-project/app/src/main/java/com/erroratline0/infinipaint/InfiniPaint.java +++ b/android-project/app/src/main/java/com/erroratline0/infinipaint/InfiniPaint.java @@ -36,6 +36,7 @@ import org.libsdl.app.SDLDummyEdit; import org.libsdl.app.SDLSurface; public class InfiniPaint extends SDLActivity { + public static native void androidOnStop(); protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); @@ -50,6 +51,11 @@ public class InfiniPaint extends SDLActivity { // window.setNavigationBarContrastEnforced(false); } + protected void onStop() { + androidOnStop(); + super.onStop(); + } + protected SDLSurface createSDLSurface(Context context) { return new InfiniPaintSurface(context); } diff --git a/src/AndroidJNICalls.cpp b/src/AndroidJNICalls.cpp index 4a17666..4a4d9dd 100644 --- a/src/AndroidJNICalls.cpp +++ b/src/AndroidJNICalls.cpp @@ -49,6 +49,7 @@ jstring string2jstring(JNIEnv* env, const std::string& s) { namespace AndroidJNICalls { InputManager* globalInputManager; + std::mutex globalMutex; std::mutex textboxMutex; CustomEvents::InputTextBoxID textboxID = 0; @@ -345,4 +346,12 @@ Java_com_erroratline0_infinipaint_InfiniPaintNetworkService_networkServiceDestro NetThreadManager::get().destroy_thread(); } -#endif +extern "C" +JNIEXPORT void JNICALL +Java_com_erroratline0_infinipaint_InfiniPaint_androidOnStop(JNIEnv *env, jclass clazz) { + std::scoped_lock a{globalMutex}; + if(AndroidJNICalls::globalInputManager) + AndroidJNICalls::globalInputManager->main.input_android_on_stop_callback(); +} + +#endif \ No newline at end of file diff --git a/src/AndroidJNICalls.hpp b/src/AndroidJNICalls.hpp index e947866..8c7aa1f 100644 --- a/src/AndroidJNICalls.hpp +++ b/src/AndroidJNICalls.hpp @@ -25,6 +25,7 @@ struct InputManager; namespace AndroidJNICalls { extern InputManager* globalInputManager; + extern std::mutex globalMutex; void startTextInput(CustomEvents::InputTextBoxID newTextboxID, const std::shared_ptr& newTextbox, const std::shared_ptr& newCursor, const std::shared_ptr& modMap, int inputType); void startNetworkService(); diff --git a/src/MainProgram.cpp b/src/MainProgram.cpp index ca0650a..eb354da 100755 --- a/src/MainProgram.cpp +++ b/src/MainProgram.cpp @@ -365,17 +365,18 @@ void MainProgram::post_callback() { g.gui.layout_if_necessary(); } -void MainProgram::input_app_about_to_go_to_background_callback() { - screen->input_app_about_to_go_to_background_callback(); +void MainProgram::input_android_on_stop_callback() { + Logger::get().log(Logger::LogType::INFO, "[input_android_on_stop_callback] onStop received"); save_config(); - post_callback(); + screen->input_android_on_stop_callback(); +} + +void MainProgram::input_app_about_to_go_to_background_callback() { NetThreadManager::get().go_to_background(); } void MainProgram::input_app_about_to_go_to_foreground_callback() { NetThreadManager::get().go_to_foreground(); - screen->input_app_about_to_go_to_foreground_callback(); - post_callback(); } void MainProgram::input_add_file_to_canvas_callback(const CustomEvents::AddFileToCanvasEvent& addFile) { diff --git a/src/MainProgram.hpp b/src/MainProgram.hpp index 81194df..a6e39f3 100644 --- a/src/MainProgram.hpp +++ b/src/MainProgram.hpp @@ -162,6 +162,7 @@ class MainProgram { void input_paste_callback(const CustomEvents::PasteEvent& paste); void input_android_text_box_input_callback(const CustomEvents::AndroidTextBoxInputEvent& textboxInput); + void input_android_on_stop_callback(); void input_app_about_to_go_to_background_callback(); void input_app_about_to_go_to_foreground_callback(); void input_global_back_button_callback(); diff --git a/src/Screens/FileSelectScreen.cpp b/src/Screens/FileSelectScreen.cpp index 1f19a7e..eb92216 100644 --- a/src/Screens/FileSelectScreen.cpp +++ b/src/Screens/FileSelectScreen.cpp @@ -1202,6 +1202,12 @@ void FileSelectScreen::input_global_back_button_callback() { mainMenuOpenAnim->animation_trigger_reverse(); else if(editMode) editMode = false; + else if(selectedMenu != SelectedMenu::FILES) { + selectedMenu = SelectedMenu::FILES; + update_file_list(fileList, savePath, false); + mainMenuOpenAnim->animation_trigger_reverse(); + if(mainViewScrollArea) mainViewScrollArea->reset_scroll(); + } else main.setToQuit = true; main.g.gui.set_to_layout(); @@ -1218,7 +1224,7 @@ void FileSelectScreen::save_files() { SDL_SaveFile(infoPath.string().c_str(), saveJson.c_str(), saveJson.size()); } -void FileSelectScreen::input_app_about_to_go_to_background_callback() { +void FileSelectScreen::input_android_on_stop_callback() { save_files(); } diff --git a/src/Screens/FileSelectScreen.hpp b/src/Screens/FileSelectScreen.hpp index a2f5812..89550cd 100644 --- a/src/Screens/FileSelectScreen.hpp +++ b/src/Screens/FileSelectScreen.hpp @@ -31,7 +31,7 @@ class FileSelectScreen : public Screen { virtual void input_paste_callback(const CustomEvents::PasteEvent& paste) override; virtual void input_open_infinipaint_file_callback(const CustomEvents::OpenInfiniPaintFileEvent& openFile) override; virtual void input_global_back_button_callback() override; - virtual void input_app_about_to_go_to_background_callback() override; + virtual void input_android_on_stop_callback() override; struct TrashInfo { struct TrashFile { diff --git a/src/Screens/PhoneDrawingProgramScreen.cpp b/src/Screens/PhoneDrawingProgramScreen.cpp index 7210a18..f4f28b4 100644 --- a/src/Screens/PhoneDrawingProgramScreen.cpp +++ b/src/Screens/PhoneDrawingProgramScreen.cpp @@ -443,7 +443,7 @@ void PhoneDrawingProgramScreen::top_toolbar() { svg_icon_button(gui, "back exit button", "data/icons/RemixIcon/arrow-left-s-line.svg", { .drawType = SelectableButton::DrawType::TRANSPARENT_ALL, .onClick = [&] { - save_to_file(); + save_to_file(true); main.set_tab_to_close(main.world.get()); } }); @@ -1231,19 +1231,19 @@ void PhoneDrawingProgramScreen::input_global_back_button_callback() { main.g.gui.set_to_layout(); } else { - save_to_file(); + save_to_file(true); main.set_tab_to_close(main.world.get()); main.g.gui.set_to_layout(); } } -void PhoneDrawingProgramScreen::save_to_file() { +void PhoneDrawingProgramScreen::save_to_file(bool saveThumbnail) { if(!main.world->netClient) - main.world->save_to_file(main.world->filePath); + main.world->save_to_file(main.world->filePath, saveThumbnail); } -void PhoneDrawingProgramScreen::input_app_about_to_go_to_background_callback() { - save_to_file(); +void PhoneDrawingProgramScreen::input_android_on_stop_callback() { + save_to_file(false); // not saving thumbnail for now, since thumbnail requires GPU } void PhoneDrawingProgramScreen::on_tab_close() { @@ -1274,3 +1274,9 @@ void PhoneDrawingProgramScreen::color_selector_button(const char* id, Vector4f* } }); } + +PhoneDrawingProgramScreen::~PhoneDrawingProgramScreen() { +#ifndef __ANDROID__ + save_to_file(true); +#endif +} diff --git a/src/Screens/PhoneDrawingProgramScreen.hpp b/src/Screens/PhoneDrawingProgramScreen.hpp index 02cf32e..11e5368 100644 --- a/src/Screens/PhoneDrawingProgramScreen.hpp +++ b/src/Screens/PhoneDrawingProgramScreen.hpp @@ -24,10 +24,11 @@ class PhoneDrawingProgramScreen : public DrawingProgramScreen { public: PhoneDrawingProgramScreen(MainProgram& m); + ~PhoneDrawingProgramScreen(); virtual void update() override; virtual void gui_layout_run() override; virtual void input_global_back_button_callback() override; - virtual void input_app_about_to_go_to_background_callback() override; + virtual void input_android_on_stop_callback() override; virtual void on_tab_close() override; struct ColorSelectorData { std::function onChange; @@ -100,7 +101,7 @@ class PhoneDrawingProgramScreen : public DrawingProgramScreen { void bottom_toolbar(); void main_display(); void tool_settings_popup(); - void save_to_file(); + void save_to_file(bool saveThumbnail); std::string serverToConnectTo; std::string serverLocalID; diff --git a/src/Screens/Screen.cpp b/src/Screens/Screen.cpp index 50189f8..3da2816 100644 --- a/src/Screens/Screen.cpp +++ b/src/Screens/Screen.cpp @@ -82,8 +82,7 @@ void Screen::input_finger_touch_callback(const InputManager::FingerTouchCallback void Screen::input_finger_motion_callback(const InputManager::FingerMotionCallbackArgs& motion) {} void Screen::input_window_resize_callback(const InputManager::WindowResizeCallbackArgs& w) {} void Screen::input_window_scale_callback(const InputManager::WindowScaleCallbackArgs& w) {} -void Screen::input_app_about_to_go_to_background_callback() {} -void Screen::input_app_about_to_go_to_foreground_callback() {} +void Screen::input_android_on_stop_callback() {} void Screen::on_tab_close() {} float Screen::calculate_gui_scale() { return main.g.final_gui_scale_not_fit(); } std::optional Screen::get_text_box_start_info() { return std::nullopt; } diff --git a/src/Screens/Screen.hpp b/src/Screens/Screen.hpp index 3ab9f55..c820eac 100644 --- a/src/Screens/Screen.hpp +++ b/src/Screens/Screen.hpp @@ -64,8 +64,7 @@ class Screen { virtual void input_finger_motion_callback(const InputManager::FingerMotionCallbackArgs& motion); virtual void input_window_resize_callback(const InputManager::WindowResizeCallbackArgs& w); virtual void input_window_scale_callback(const InputManager::WindowScaleCallbackArgs& w); - virtual void input_app_about_to_go_to_background_callback(); - virtual void input_app_about_to_go_to_foreground_callback(); + virtual void input_android_on_stop_callback(); virtual float calculate_gui_scale(); virtual void on_tab_close(); virtual std::optional get_text_box_start_info(); diff --git a/src/World.cpp b/src/World.cpp index b0c5899..63b4a5a 100644 --- a/src/World.cpp +++ b/src/World.cpp @@ -476,7 +476,7 @@ void World::autosave_to_directory(const std::filesystem::path& directoryToSaveAt save_to_file(directoryToSaveAt / std::filesystem::path(nameToSaveUnder + "." + FILE_EXTENSION)); } -void World::save_to_file(const std::filesystem::path& filePathToSaveAt) { +void World::save_to_file(const std::filesystem::path& filePathToSaveAt, bool saveThumbnailIfAvailable) { try { filePath = filePathToSaveAt; @@ -508,7 +508,7 @@ void World::save_to_file(const std::filesystem::path& filePathToSaveAt) { #else if(!SDL_SaveFile(filePath.string().c_str(), f.view().data(), f.view().size())) throw std::runtime_error("SDL_SaveFile failed with error: " + std::string(SDL_GetError())); - else if(saveThumbnail) { + else if(saveThumbnail && saveThumbnailIfAvailable) { Vector2f imageCenter{main.window.size.x() * 0.5f, main.window.size.y() * 0.5f}; float imageDim = std::max(main.window.size.x(), main.window.size.y()); Vector2f imageDimVec{imageDim * 0.5f, imageDim * 0.5f}; diff --git a/src/World.hpp b/src/World.hpp index 2f0afc5..d596983 100644 --- a/src/World.hpp +++ b/src/World.hpp @@ -84,7 +84,7 @@ class World { bool clientStillConnecting = false; void autosave_to_directory(const std::filesystem::path& directoryToSaveAt); - void save_to_file(const std::filesystem::path& filePathToSaveAt); + void save_to_file(const std::filesystem::path& filePathToSaveAt, bool saveThumbnailIfAvailable = true); void load_from_file(const std::filesystem::path& filePathToLoadFrom, std::string_view buffer); void undo_with_checks(); diff --git a/src/main.cpp b/src/main.cpp index 21b2e13..068b8fc 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -616,6 +616,9 @@ void regular_draw(MainStruct& mS) { } SDL_AppResult SDL_AppIterate(void *appstate) { +#ifdef __ANDROID__ + std::scoped_lock a{AndroidJNICalls::globalMutex}; +#endif std::chrono::steady_clock::time_point frameTimeStart = std::chrono::steady_clock::now(); MainStruct& mS = *((MainStruct*)appstate); @@ -626,12 +629,8 @@ SDL_AppResult SDL_AppIterate(void *appstate) { #endif mS.m->update(); - if(mS.m->setToQuit) { - #ifdef __ANDROID__ - mS.m->input_app_about_to_go_to_background_callback(); - #endif + if(mS.m->setToQuit) return SDL_APP_SUCCESS; - } if(mS.m->input.hideCursor) { SDL_HideCursor(); @@ -659,6 +658,10 @@ SDL_AppResult SDL_AppIterate(void *appstate) { } SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) { +#ifdef __ANDROID__ + std::scoped_lock a{AndroidJNICalls::globalMutex}; +#endif + MainStruct& mS = *((MainStruct*)appstate); #ifdef NDEBUG @@ -840,12 +843,8 @@ SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) { } #endif - if(mS.m->setToQuit) { - #ifdef __ANDROID__ - mS.m->input_app_about_to_go_to_background_callback(); - #endif + if(mS.m->setToQuit) return SDL_APP_SUCCESS; - } return SDL_APP_CONTINUE; }