diff --git a/src/GUIHolder.cpp b/src/GUIHolder.cpp index 337cf54..aa7823c 100644 --- a/src/GUIHolder.cpp +++ b/src/GUIHolder.cpp @@ -167,8 +167,3 @@ void GUIHolder::input_finger_touch_callback(const InputManager::FingerTouchCallb void GUIHolder::input_finger_motion_callback(const InputManager::FingerMotionCallbackArgs& motion) { } - -void GUIHolder::post_callback() { - gui.run_post_callback_func(); - gui.layout_if_necessary(); -} diff --git a/src/GUIHolder.hpp b/src/GUIHolder.hpp index 7ce9548..6fed5ea 100644 --- a/src/GUIHolder.hpp +++ b/src/GUIHolder.hpp @@ -33,8 +33,6 @@ class GUIHolder { void input_finger_touch_callback(const InputManager::FingerTouchCallbackArgs& touch); void input_finger_motion_callback(const InputManager::FingerMotionCallbackArgs& motion); - void post_callback(); - float final_gui_scale(); private: void calculate_final_gui_scale(); diff --git a/src/MainProgram.cpp b/src/MainProgram.cpp index de8faee..1f126de 100755 --- a/src/MainProgram.cpp +++ b/src/MainProgram.cpp @@ -263,13 +263,16 @@ void MainProgram::switch_to_tab(size_t wIndex) { worldIndex = wIndex; } -void MainProgram::input_app_terminate_callback() { - screen->input_app_terminate_callback(); +void MainProgram::post_callback() { + g.gui.run_post_callback_func(); + run_new_screen_func(); + close_set_to_close_tabs(); + g.gui.layout_if_necessary(); } -void MainProgram::post_callback() { - close_set_to_close_tabs(); - g.post_callback(); +void MainProgram::input_app_about_to_go_to_background_callback() { + screen->input_app_about_to_go_to_background_callback(); + post_callback(); } void MainProgram::input_add_file_to_canvas_callback(const CustomEvents::AddFileToCanvasEvent& addFile) { @@ -422,10 +425,22 @@ void MainProgram::toggle_full_screen() { SDL_SetWindowFullscreen(window.sdlWindow, window.fullscreen); } -void MainProgram::set_screen(std::unique_ptr newScreen) { - screen = std::move(newScreen); - g.gui.set_to_layout(); - g.gui.io.redrawSurface = true; +void MainProgram::set_first_screen(std::unique_ptr firstScreen) { + set_screen([&](std::unique_ptr){ return std::move(firstScreen); }); + run_new_screen_func(); +} + +void MainProgram::run_new_screen_func() { + if(newScreenFunc) { + screen = newScreenFunc(std::move(screen)); + g.gui.io.redrawSurface = true; + g.gui.set_to_layout(); + newScreenFunc = nullptr; + } +} + +void MainProgram::set_screen(std::function(std::unique_ptr)> screenFunc) { + newScreenFunc = screenFunc; } void MainProgram::close_set_to_close_tabs() { diff --git a/src/MainProgram.hpp b/src/MainProgram.hpp index 4c68673..3483fd9 100644 --- a/src/MainProgram.hpp +++ b/src/MainProgram.hpp @@ -114,7 +114,9 @@ class MainProgram { float get_scale_and_density_factor_gui(); bool app_close_requested(); void toggle_full_screen(); - void set_screen(std::unique_ptr newScreen); + + void set_first_screen(std::unique_ptr firstScreen); + void set_screen(std::function(std::unique_ptr)> screenFunc); void refresh_draw_surfaces(); @@ -134,7 +136,7 @@ class MainProgram { void input_open_infinipaint_file_callback(const CustomEvents::OpenInfiniPaintFileEvent& openFile); void input_paste_callback(const CustomEvents::PasteEvent& paste); - void input_app_terminate_callback(); + void input_app_about_to_go_to_background_callback(); void input_global_back_button_callback(); bool input_keybind_callback(const Vector2ui32& newKey); void input_drop_file_callback(const InputManager::DropCallbackArgs& drop); @@ -165,8 +167,10 @@ class MainProgram { std::unordered_set tabsToClose; void close_set_to_close_tabs(); void post_callback(); + void run_new_screen_func(); std::string gen_random_display_name(); + std::function(std::unique_ptr)> newScreenFunc; std::unique_ptr screen; void gui(); diff --git a/src/Screens/FileSelectScreen.cpp b/src/Screens/FileSelectScreen.cpp index 7d8e6f0..391bf97 100644 --- a/src/Screens/FileSelectScreen.cpp +++ b/src/Screens/FileSelectScreen.cpp @@ -207,7 +207,7 @@ void FileSelectScreen::create_file_button() { .isClient = false, .filePathEmptyAutoSaveDir = savePath }); - main.set_screen(std::make_unique(main)); + main.set_screen([&] (std::unique_ptr) { return std::make_unique(main); }); } }); } @@ -257,6 +257,7 @@ void FileSelectScreen::move_selected_files(const std::filesystem::path& fromPath for(const FileInfo& f : fileList) { if(f.selected) { std::string newFileName = ensure_string_unique(toFolderListNames, f.fileName); + toFolderListNames.emplace_back(newFileName); std::filesystem::path filePath = fromPath / (f.fileName + World::DOT_FILE_EXTENSION); std::filesystem::path thumbnailPath = fromPath / (f.fileName + ".jpg"); std::filesystem::path newFilePath = toPath / (newFileName + World::DOT_FILE_EXTENSION); @@ -290,6 +291,7 @@ void FileSelectScreen::duplicate_selected_files(const std::filesystem::path& inP for(const FileInfo& f : fileList) { if(f.selected) { std::string newFileName = ensure_string_unique(toFolderListNames, f.fileName); + toFolderListNames.emplace_back(newFileName); std::filesystem::path filePath = inPath / (f.fileName + World::DOT_FILE_EXTENSION); std::filesystem::path thumbnailPath = inPath / (f.fileName + ".jpg"); std::filesystem::path newFilePath = inPath / (newFileName + World::DOT_FILE_EXTENSION); @@ -670,15 +672,15 @@ void FileSelectScreen::file_view() { Vector2f iconSize{0.0f, 0.0f}; switch(fileViewType) { case FileViewType::LARGE_GRID: - entrySize = {170.0f, 190.0f}; + entrySize = {170.0f, 210.0f}; iconSize = {130.0f, 130.0f}; break; case FileViewType::MEDIUM_GRID: - entrySize = {140.0f, 160.0f}; + entrySize = {140.0f, 180.0f}; iconSize = {100.0f, 100.0f}; break; case FileViewType::SMALL_GRID: - entrySize = {110.0f, 130.0f}; + entrySize = {110.0f, 150.0f}; iconSize = {70.0f, 70.0f}; break; default: @@ -736,7 +738,7 @@ void FileSelectScreen::start_edit_mode() { void FileSelectScreen::input_open_infinipaint_file_callback(const CustomEvents::OpenInfiniPaintFileEvent& openFile) { main.create_new_tab(openFile); - main.set_screen(std::make_unique(main)); + main.set_screen([&] (std::unique_ptr) { return std::make_unique(main); }); } void FileSelectScreen::input_global_back_button_callback() { @@ -753,9 +755,19 @@ void FileSelectScreen::draw(SkCanvas* canvas) { canvas->clear(main.g.gui.io.theme->backColor0); } -FileSelectScreen::~FileSelectScreen() { +void FileSelectScreen::save_files() { nlohmann::json j; nlohmann::to_json(j, trashInfo); std::string saveJson = nlohmann::to_string(j); SDL_SaveFile(trashInfoPath.string().c_str(), saveJson.c_str(), saveJson.size()); } + +void FileSelectScreen::input_app_about_to_go_to_background_callback() { + save_files(); +} + +FileSelectScreen::~FileSelectScreen() { +#ifndef __ANDROID__ + save_files(); +#endif +} diff --git a/src/Screens/FileSelectScreen.hpp b/src/Screens/FileSelectScreen.hpp index e868afb..397ac5a 100644 --- a/src/Screens/FileSelectScreen.hpp +++ b/src/Screens/FileSelectScreen.hpp @@ -1,7 +1,7 @@ #pragma once #include "Screen.hpp" #include "nlohmann/json.hpp" -#include "../GUIStuff/GUIManager.hpp" +#include "../GUIStuff/GUIFloatAnimation.hpp" class FileSelectScreen : public Screen { public: @@ -10,6 +10,7 @@ class FileSelectScreen : public Screen { virtual void draw(SkCanvas* canvas) 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; struct TrashInfo { struct TrashFile { @@ -26,6 +27,8 @@ class FileSelectScreen : public Screen { std::filesystem::path trashPath; std::filesystem::path trashInfoPath; + void save_files(); + struct FileInfo { std::string fileName; SDL_Time lastModifyTime; diff --git a/src/Screens/PhoneDrawingProgramScreen.cpp b/src/Screens/PhoneDrawingProgramScreen.cpp index 5bf23be..1685755 100644 --- a/src/Screens/PhoneDrawingProgramScreen.cpp +++ b/src/Screens/PhoneDrawingProgramScreen.cpp @@ -59,7 +59,7 @@ void PhoneDrawingProgramScreen::top_toolbar() { .onClick = [&] { main.world->save_to_file(main.world->filePath); main.set_tab_to_close(main.world.get()); - main.set_screen(std::make_unique(main)); + main.set_screen([&] (std::unique_ptr) { return std::make_unique(main); }); } }); text_label(gui, main.world->name); @@ -70,15 +70,10 @@ void PhoneDrawingProgramScreen::top_toolbar() { void PhoneDrawingProgramScreen::input_global_back_button_callback() { main.world->save_to_file(main.world->filePath); main.set_tab_to_close(main.world.get()); - main.set_screen(std::make_unique(main)); main.g.gui.set_to_layout(); + main.set_screen([&] (std::unique_ptr) { return std::make_unique(main); }); } -bool PhoneDrawingProgramScreen::app_close_requested() { - main.world->save_to_file(main.world->filePath); - return true; -} - -void PhoneDrawingProgramScreen::input_app_terminate_callback() { +void PhoneDrawingProgramScreen::input_app_about_to_go_to_background_callback() { main.world->save_to_file(main.world->filePath); } diff --git a/src/Screens/PhoneDrawingProgramScreen.hpp b/src/Screens/PhoneDrawingProgramScreen.hpp index 976d59c..44dfda2 100644 --- a/src/Screens/PhoneDrawingProgramScreen.hpp +++ b/src/Screens/PhoneDrawingProgramScreen.hpp @@ -8,9 +8,9 @@ class PhoneDrawingProgramScreen : public DrawingProgramScreen { virtual void update() override; virtual void gui_layout_run() override; virtual void input_global_back_button_callback() override; - virtual bool app_close_requested() override; - virtual void input_app_terminate_callback() override; + virtual void input_app_about_to_go_to_background_callback() override; private: + void save_files(); void top_toolbar(); void main_display(); }; diff --git a/src/Screens/Screen.cpp b/src/Screens/Screen.cpp index 64847d2..60aaf07 100644 --- a/src/Screens/Screen.cpp +++ b/src/Screens/Screen.cpp @@ -29,6 +29,6 @@ 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_terminate_callback() {} +void Screen::input_app_about_to_go_to_background_callback() {} Screen::~Screen() {} diff --git a/src/Screens/Screen.hpp b/src/Screens/Screen.hpp index dfccb90..a14f2bc 100644 --- a/src/Screens/Screen.hpp +++ b/src/Screens/Screen.hpp @@ -31,7 +31,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_terminate_callback(); + virtual void input_app_about_to_go_to_background_callback(); virtual ~Screen(); protected: diff --git a/src/main.cpp b/src/main.cpp index 01575bc..d78d579 100755 --- a/src/main.cpp +++ b/src/main.cpp @@ -527,7 +527,7 @@ SDL_AppResult SDL_AppInit(void **appstate, int argc, char **argv) { mS.m->window.canCreateSurfaces = true; resize_window(mS); - mS.m->set_screen(std::make_unique(*mS.m)); + mS.m->set_first_screen(std::make_unique(*mS.m)); if(listOfFilesToOpenFromCommand.empty()) { //mS.m->create_new_tab({ @@ -638,10 +638,10 @@ SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) { if(mS.m->app_close_requested()) return SDL_APP_SUCCESS; break; - case SDL_EVENT_TERMINATING: - Logger::get().log("INFO", "[SDL_AppEvent] Terminate"); - mS.m->input_app_terminate_callback(); - return SDL_APP_SUCCESS; + case SDL_EVENT_WILL_ENTER_BACKGROUND: + Logger::get().log("INFO", "[SDL_AppEvent] Entering background"); + mS.m->input_app_about_to_go_to_background_callback(); + break; case SDL_EVENT_WINDOW_CLOSE_REQUESTED: if(event->window.windowID == SDL_GetWindowID(mS.window)) { if(mS.m->app_close_requested()) @@ -798,7 +798,9 @@ SDL_AppResult SDL_AppEvent(void *appstate, SDL_Event *event) { return mS.m->setToQuit ? SDL_APP_SUCCESS : SDL_APP_CONTINUE; } +// NOTE: On Android, SDL_AppQuit is triggered by onDestroy. onDestroy may or may not be called, and even if it is, it may only be partially called. You should not rely on it. void SDL_AppQuit(void *appstate, SDL_AppResult result) { +#ifndef __ANDROID__ DrawingProgramCache::delete_all_draw_cache(); MainStruct& mS = *((MainStruct*)appstate); @@ -816,4 +818,5 @@ void SDL_AppQuit(void *appstate, SDL_AppResult result) { SDL_Quit(); FileDownloader::cleanup(); +#endif }