#include "pch.h" #include "platform_legacy/legacy_platform_services.h" #include "app.h" #include "app_core/document_platform_io.h" #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 __APPLE__ #elif __LINUX__ #include #elif __WEB__ void webgl_pick_file(std::function callback); void webgl_pick_file_save( const std::string& path, const std::string& name, std::function callback); void webgl_sync(); #endif namespace { void invoke_picked_path_if_selected( const std::string& path, const std::function& callback) { if (pp::app::plan_picked_path(path) == pp::app::PickedPathAction::invoke_callback) callback(path); } // DEBT-0017: fallback for platforms that do not inject PlatformServices yet. class LegacyPlatformServices final : public pp::platform::PlatformServices { public: [[nodiscard]] std::string clipboard_text() override { #if __IOS__ return [App::I->ios_view clipboard_get_string]; #elif __OSX__ return [App::I->osx_view clipboard_get_string]; #elif __ANDROID__ return android_get_clipboard(); #else return {}; #endif } [[nodiscard]] bool set_clipboard_text(std::string_view text) override { const std::string value(text); #if __IOS__ return [App::I->ios_view clipboard_set_string:value]; #elif __OSX__ return [App::I->osx_view clipboard_set_string:value]; #elif __ANDROID__ return android_set_clipboard(value); #else return false; #endif } void set_cursor_visible(bool visible) override { #ifdef __OSX__ [App::I->osx_view show_cursor:visible]; #else (void)visible; #endif } void set_virtual_keyboard_visible(bool visible) override { #ifdef __IOS__ dispatch_async(dispatch_get_main_queue(), ^{ if (visible) [App::I->ios_view show_keyboard]; else [App::I->ios_view hide_keyboard]; }); #elif __ANDROID__ displayKeyboard(visible); #else (void)visible; #endif } void pick_image(pp::platform::PickedPathCallback callback) override { #ifdef __IOS__ dispatch_async(dispatch_get_main_queue(), ^{ [App::I->ios_view pick_photo:callback]; }); #elif __OSX__ dispatch_async(dispatch_get_main_queue(), ^{ NSArray* fileTypes = [NSArray arrayWithObjects:@"png", @"PNG", @"jpg", @"JPG", @"jpeg", nil]; std::string path = [App::I->osx_view pick_file:fileTypes]; invoke_picked_path_if_selected(path, callback); }); #elif __ANDROID__ android_pick_file(callback); #elif __LINUX__ if (auto p = tinyfd_openFileDialog("Open File", "", 0, nullptr, nullptr, false)) invoke_picked_path_if_selected(p, callback); #elif __WEB__ webgl_pick_file(callback); #else (void)callback; #endif } void pick_file(std::vector file_types, pp::platform::PickedPathCallback callback) override { #ifdef __IOS__ dispatch_async(dispatch_get_main_queue(), ^{ NSMutableArray* fileTypes = [NSMutableArray arrayWithCapacity:file_types.size()]; for (const auto& t : file_types) [fileTypes addObject:[NSString stringWithCString:t.c_str() encoding:NSUTF8StringEncoding]]; [App::I->ios_view pick_file:fileTypes then:callback]; }); #elif __OSX__ dispatch_async(dispatch_get_main_queue(), ^{ NSMutableArray* fileTypes = [NSMutableArray arrayWithCapacity:file_types.size()]; for (const auto& t : file_types) [fileTypes addObject:[NSString stringWithCString:t.c_str() encoding:NSUTF8StringEncoding]]; std::string path = [App::I->osx_view pick_file:fileTypes]; invoke_picked_path_if_selected(path, callback); }); #elif __ANDROID__ android_pick_file(callback); #elif __LINUX__ if (auto p = tinyfd_openFileDialog("Open File", "", 0, nullptr, nullptr, false)) invoke_picked_path_if_selected(p, callback); #elif __WEB__ webgl_pick_file(callback); #else (void)file_types; (void)callback; #endif } void pick_save_file(std::vector file_types, pp::platform::PickedPathCallback callback) override { #if __OSX__ dispatch_async(dispatch_get_main_queue(), ^{ NSMutableArray* fileTypes = [NSMutableArray arrayWithCapacity:file_types.size()]; for (const auto& t : file_types) [fileTypes addObject:[NSString stringWithCString:t.c_str() encoding:NSUTF8StringEncoding]]; std::string path = [App::I->osx_view pick_file_save:fileTypes]; invoke_picked_path_if_selected(path, callback); }); #elif __ANDROID__ android_pick_file_save(callback); #else (void)file_types; (void)callback; #endif } void pick_directory(pp::platform::PickedPathCallback callback) override { #ifdef __IOS__ (void)callback; #elif __OSX__ dispatch_async(dispatch_get_main_queue(), ^{ std::string path = [App::I->osx_view pick_dir]; invoke_picked_path_if_selected(path, callback); }); #elif __ANDROID__ (void)callback; #else (void)callback; #endif } void display_file(std::string_view path) override { const std::string value(path); #ifdef __IOS__ dispatch_async(dispatch_get_main_queue(), ^{ [App::I->ios_view display_file:value]; }); #elif __OSX__ [[NSWorkspace sharedWorkspace] openFile:[NSString stringWithUTF8String:value.c_str()]]; #else (void)value; #endif } void share_file(std::string_view path) override { const std::string value(path); #ifdef __IOS__ dispatch_async(dispatch_get_main_queue(), ^{ [App::I->ios_view share_file:[NSString stringWithUTF8String:value.c_str()]]; }); #elif __OSX__ dispatch_async(dispatch_get_main_queue(), ^{ [App::I->osx_view share_file:[NSString stringWithUTF8String:value.c_str()]]; }); #else (void)value; #endif } void request_app_close() override { #ifdef __OSX__ dispatch_async(dispatch_get_main_queue(), ^{ [App::I->osx_view close]; }); #elif __LINUX__ glfwSetWindowShouldClose(App::I->glfw_window, GLFW_TRUE); #endif } void save_prepared_file( std::string_view path, std::string_view suggested_name, pp::platform::PreparedFileCallback callback) override { const std::string value(path); const std::string name(suggested_name); #ifdef __IOS__ (void)name; dispatch_async(dispatch_get_main_queue(), ^{ [App::I->ios_view pick_file_save:value]; }); callback(value, true); #elif __WEB__ webgl_pick_file_save(value, name, [callback = std::move(callback), value](bool success) { callback(value, success); }); #else (void)name; callback(value, false); #endif } }; } namespace pp::platform::legacy { PlatformServices& platform_services() { static LegacyPlatformServices services; return services; } }