From d4c541c25a6533ebb966ddaa581523fe9326433a Mon Sep 17 00:00:00 2001 From: Sergey Minakov Date: Tue, 7 Jul 2020 00:01:35 +0300 Subject: [PATCH 1/2] iOS Export: add option to use storyboard for launch screen --- .../godot_ios.xcodeproj/project.pbxproj | 8 +- .../SplashImage.imageset/Contents.json | 22 ++++ .../SplashImage.imageset/splash@2x.png | Bin 0 -> 21443 bytes .../SplashImage.imageset/splash@3x.png | Bin 0 -> 21443 bytes .../godot_ios/Launch Screen.storyboard | 41 ++++++ .../ios_xcode/godot_ios/godot_ios-Info.plist | 1 + platform/iphone/export/export.cpp | 123 +++++++++++++++++- 7 files changed, 190 insertions(+), 5 deletions(-) create mode 100644 misc/dist/ios_xcode/godot_ios/Images.xcassets/SplashImage.imageset/Contents.json create mode 100644 misc/dist/ios_xcode/godot_ios/Images.xcassets/SplashImage.imageset/splash@2x.png create mode 100644 misc/dist/ios_xcode/godot_ios/Images.xcassets/SplashImage.imageset/splash@3x.png create mode 100644 misc/dist/ios_xcode/godot_ios/Launch Screen.storyboard diff --git a/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj b/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj index 8c92ae2a7c..54dda2563d 100644 --- a/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj +++ b/misc/dist/ios_xcode/godot_ios.xcodeproj/project.pbxproj @@ -14,6 +14,7 @@ D07CD44E1C5D589C00B7FB28 /* Images.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = D07CD44D1C5D589C00B7FB28 /* Images.xcassets */; }; D0BCFE4618AEBDA2004A7AAE /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = D0BCFE4418AEBDA2004A7AAE /* InfoPlist.strings */; }; D0BCFE7818AEBFEB004A7AAE /* $binary.pck in Resources */ = {isa = PBXBuildFile; fileRef = D0BCFE7718AEBFEB004A7AAE /* $binary.pck */; }; + $pbx_launch_screen_build_reference /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -41,6 +42,7 @@ D0BCFE4318AEBDA2004A7AAE /* $binary-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "$binary-Info.plist"; sourceTree = ""; }; D0BCFE4518AEBDA2004A7AAE /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = ""; }; D0BCFE7718AEBFEB004A7AAE /* $binary.pck */ = {isa = PBXFileReference; lastKnownFileType = file; path = "$binary.pck"; sourceTree = ""; }; + $pbx_launch_screen_file_reference /* End PBXFileReference section */ $additional_pbx_files @@ -92,6 +94,7 @@ D0BCFE4118AEBDA2004A7AAE /* $binary */ = { isa = PBXGroup; children = ( + $pbx_launch_screen_copy_files 1FF4C1881F584E6300A41E41 /* $binary.entitlements */, D07CD44D1C5D589C00B7FB28 /* Images.xcassets */, D0BCFE4218AEBDA2004A7AAE /* Supporting Files */, @@ -247,6 +250,7 @@ files = ( D07CD44E1C5D589C00B7FB28 /* Images.xcassets in Resources */, D0BCFE7818AEBFEB004A7AAE /* $binary.pck in Resources */, + $pbx_launch_screen_build_phase D0BCFE4618AEBDA2004A7AAE /* InfoPlist.strings in Resources */, $additional_pbx_resources_build ); @@ -367,7 +371,7 @@ buildSettings = { ARCHS = "$godot_archs"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + $pbx_launch_image_usage_setting CODE_SIGN_ENTITLEMENTS = "$binary/$binary.entitlements"; CODE_SIGN_IDENTITY = "$code_sign_identity_debug"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "$code_sign_identity_debug"; @@ -397,7 +401,7 @@ buildSettings = { ARCHS = "$godot_archs"; ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage; + $pbx_launch_image_usage_setting CODE_SIGN_ENTITLEMENTS = "$binary/$binary.entitlements"; CODE_SIGN_IDENTITY = "$code_sign_identity_release"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "$code_sign_identity_release"; diff --git a/misc/dist/ios_xcode/godot_ios/Images.xcassets/SplashImage.imageset/Contents.json b/misc/dist/ios_xcode/godot_ios/Images.xcassets/SplashImage.imageset/Contents.json new file mode 100644 index 0000000000..1e63e78eda --- /dev/null +++ b/misc/dist/ios_xcode/godot_ios/Images.xcassets/SplashImage.imageset/Contents.json @@ -0,0 +1,22 @@ +{ + "images" : [ + { + "idiom" : "universal", + "scale" : "1x" + }, + { + "filename" : "splash@2x.png", + "idiom" : "universal", + "scale" : "2x" + }, + { + "filename" : "splash@3x.png", + "idiom" : "universal", + "scale" : "3x" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/misc/dist/ios_xcode/godot_ios/Images.xcassets/SplashImage.imageset/splash@2x.png b/misc/dist/ios_xcode/godot_ios/Images.xcassets/SplashImage.imageset/splash@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..766b0b66efb1ac8cb53d9cd6b7fa2ef70c6ec559 GIT binary patch literal 21443 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 HP6 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/misc/dist/ios_xcode/godot_ios/godot_ios-Info.plist b/misc/dist/ios_xcode/godot_ios/godot_ios-Info.plist index e0cad2e7d1..e9d22f6b4d 100644 --- a/misc/dist/ios_xcode/godot_ios/godot_ios-Info.plist +++ b/misc/dist/ios_xcode/godot_ios/godot_ios-Info.plist @@ -57,5 +57,6 @@ $interface_orientations $additional_plist_content + $plist_launch_screen_name diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp index 4393a4ae9f..2033209ca9 100644 --- a/platform/iphone/export/export.cpp +++ b/platform/iphone/export/export.cpp @@ -92,7 +92,8 @@ class EditorExportPlatformIOS : public EditorExportPlatform { String _get_linker_flags(); String _get_cpp_code(); void _fix_config_file(const Ref &p_preset, Vector &pfile, const IOSConfigData &p_config, bool p_debug); - Error _export_loading_screens(const Ref &p_preset, const String &p_dest_dir); + Error _export_loading_screen_images(const Ref &p_preset, const String &p_dest_dir); + Error _export_loading_screen_file(const Ref &p_preset, const String &p_dest_dir); Error _export_icons(const Ref &p_preset, const String &p_iconset_dir); Vector _get_supported_architectures(); @@ -255,6 +256,8 @@ void EditorExportPlatformIOS::get_export_options(List *r_options) r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "optional_icons/spotlight_40x40", PROPERTY_HINT_FILE, "*.png"), "")); // Spotlight r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "optional_icons/spotlight_80x80", PROPERTY_HINT_FILE, "*.png"), "")); // Spotlight on devices with retina display + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "storyboard/use_launch_screen_storyboard"), false)); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "launch_screens/generate_missing"), false)); for (uint64_t i = 0; i < sizeof(loading_screen_infos) / sizeof(loading_screen_infos[0]); ++i) { @@ -390,6 +393,48 @@ void EditorExportPlatformIOS::_fix_config_file(const Ref &p_ } else if (lines[i].find("$photolibrary_usage_description") != -1) { String description = p_preset->get("privacy/photolibrary_usage_description"); strnew += lines[i].replace("$photolibrary_usage_description", description) + "\n"; + } else if (lines[i].find("$plist_launch_screen_name") != -1) { + bool is_on = p_preset->get("storyboard/use_launch_screen_storyboard"); + String value = is_on ? "UILaunchStoryboardName\nLaunch Screen" : ""; + strnew += lines[i].replace("$plist_launch_screen_name", value) + "\n"; + } else if (lines[i].find("$pbx_launch_screen_file_reference") != -1) { + bool is_on = p_preset->get("storyboard/use_launch_screen_storyboard"); + String value = is_on ? "90DD2D9D24B36E8000717FE1 = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.storyboard; path = \"Launch Screen.storyboard\"; sourceTree = \"\"; };" : ""; + strnew += lines[i].replace("$pbx_launch_screen_file_reference", value) + "\n"; + } else if (lines[i].find("$pbx_launch_screen_copy_files") != -1) { + bool is_on = p_preset->get("storyboard/use_launch_screen_storyboard"); + String value = is_on ? "90DD2D9D24B36E8000717FE1 /* Launch Screen.storyboard */," : ""; + strnew += lines[i].replace("$pbx_launch_screen_copy_files", value) + "\n"; + } else if (lines[i].find("$pbx_launch_screen_build_phase") != -1) { + bool is_on = p_preset->get("storyboard/use_launch_screen_storyboard"); + String value = is_on ? "90DD2D9E24B36E8000717FE1 /* Launch Screen.storyboard in Resources */," : ""; + strnew += lines[i].replace("$pbx_launch_screen_build_phase", value) + "\n"; + } else if (lines[i].find("$pbx_launch_screen_build_reference") != -1) { + bool is_on = p_preset->get("storyboard/use_launch_screen_storyboard"); + String value = is_on ? "90DD2D9E24B36E8000717FE1 /* Launch Screen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 90DD2D9D24B36E8000717FE1 /* Launch Screen.storyboard */; };" : ""; + strnew += lines[i].replace("$pbx_launch_screen_build_reference", value) + "\n"; + } else if (lines[i].find("$pbx_launch_image_usage_setting") != -1) { + bool is_on = p_preset->get("storyboard/use_launch_screen_storyboard"); + String value = is_on ? "" : "ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;"; + strnew += lines[i].replace("$pbx_launch_image_usage_setting", value) + "\n"; + } else if (lines[i].find("$launch_screen_image_mode") != -1) { + String logo_path = ProjectSettings::get_singleton()->get("application/boot_splash/image"); + bool is_on = ProjectSettings::get_singleton()->get("application/boot_splash/fullsize"); + // If custom logo is not specified, Godot does not scale default one, so we should do the same. + String value = (is_on && logo_path.length() > 0) ? "scaleAspectFit" : "center"; + strnew += lines[i].replace("$launch_screen_image_mode", value) + "\n"; + } else if (lines[i].find("$launch_screen_background_color") != -1) { + Color color = ProjectSettings::get_singleton()->get("application/boot_splash/bg_color"); + const String value_format = "red=\"$red\" green=\"$green\" blue=\"$blue\" alpha=\"$alpha\""; + + Dictionary value_dictionary; + value_dictionary["red"] = color.r; + value_dictionary["green"] = color.g; + value_dictionary["blue"] = color.b; + value_dictionary["alpha"] = color.a; + String value = value_format.format(value_dictionary, "$_"); + + strnew += lines[i].replace("$launch_screen_background_color", value) + "\n"; } else { strnew += lines[i] + "\n"; } @@ -591,7 +636,42 @@ Error EditorExportPlatformIOS::_export_icons(const Ref &p_pr return OK; } -Error EditorExportPlatformIOS::_export_loading_screens(const Ref &p_preset, const String &p_dest_dir) { +Error EditorExportPlatformIOS::_export_loading_screen_file(const Ref &p_preset, const String &p_dest_dir) { + Ref splash; + + const String splash_path = ProjectSettings::get_singleton()->get("application/boot_splash/image"); + + if (!splash_path.empty()) { + splash.instance(); + const Error err = splash->load(splash_path); + if (err) { + splash.unref(); + } + } + + if (splash.is_null()) { + splash = Ref(memnew(Image(boot_splash_png))); + } + + // Using same image for both @2x and @3x + // because Godot's own boot logo uses single image for all resolutions. + // Also not using @1x image, because devices using this image variant + // are not supported by iOS 9, which is minimal target. + const String splash_png_path_2x = p_dest_dir.plus_file("splash@2x.png"); + const String splash_png_path_3x = p_dest_dir.plus_file("splash@3x.png"); + + if (splash->save_png(splash_png_path_2x) != OK) { + return ERR_FILE_CANT_WRITE; + } + + if (splash->save_png(splash_png_path_3x) != OK) { + return ERR_FILE_CANT_WRITE; + } + + return OK; +} + +Error EditorExportPlatformIOS::_export_loading_screen_images(const Ref &p_preset, const String &p_dest_dir) { DirAccess *da = DirAccess::open(p_dest_dir); ERR_FAIL_COND_V_MSG(!da, ERR_CANT_OPEN, "Cannot open directory '" + p_dest_dir + "'."); @@ -1172,6 +1252,7 @@ Error EditorExportPlatformIOS::export_project(const Ref &p_p files_to_parse.insert("godot_ios.xcodeproj/project.xcworkspace/contents.xcworkspacedata"); files_to_parse.insert("godot_ios.xcodeproj/xcshareddata/xcschemes/godot_ios.xcscheme"); files_to_parse.insert("godot_ios/godot_ios.entitlements"); + files_to_parse.insert("godot_ios/Launch Screen.storyboard"); IOSConfigData config_data = { pkg_name, @@ -1347,7 +1428,43 @@ Error EditorExportPlatformIOS::export_project(const Ref &p_p return err; } - err = _export_loading_screens(p_preset, dest_dir + binary_name + "/Images.xcassets/LaunchImage.launchimage/"); + bool use_storyboard = p_preset->get("storyboard/use_launch_screen_storyboard"); + + String launch_image_path = dest_dir + binary_name + "/Images.xcassets/LaunchImage.launchimage/"; + String splash_image_path = dest_dir + binary_name + "/Images.xcassets/SplashImage.imageset/"; + + DirAccess *launch_screen_da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); + + if (!launch_screen_da) { + return ERR_CANT_CREATE; + } + + if (use_storyboard) { + print_line("Using Launch Storyboard"); + + if (launch_screen_da->change_dir(launch_image_path) == OK) { + launch_screen_da->erase_contents_recursive(); + launch_screen_da->remove(launch_image_path); + } + + err = _export_loading_screen_file(p_preset, splash_image_path); + } else { + print_line("Using Launch Images"); + + const String launch_screen_path = dest_dir + binary_name + "/Launch Screen.storyboard"; + + launch_screen_da->remove(launch_screen_path); + + if (launch_screen_da->change_dir(splash_image_path) == OK) { + launch_screen_da->erase_contents_recursive(); + launch_screen_da->remove(splash_image_path); + } + + err = _export_loading_screen_images(p_preset, launch_image_path); + } + + memdelete(launch_screen_da); + if (err) { return err; } From 96e204bb0d9f464b634b9064d330135ee43d51d9 Mon Sep 17 00:00:00 2001 From: Sergey Minakov Date: Tue, 7 Jul 2020 01:39:57 +0300 Subject: [PATCH 2/2] iOS Export: Storyboard custom values --- platform/iphone/export/export.cpp | 108 +++++++++++++++++++++++------- 1 file changed, 82 insertions(+), 26 deletions(-) diff --git a/platform/iphone/export/export.cpp b/platform/iphone/export/export.cpp index 2033209ca9..900c60a7ac 100644 --- a/platform/iphone/export/export.cpp +++ b/platform/iphone/export/export.cpp @@ -257,6 +257,11 @@ void EditorExportPlatformIOS::get_export_options(List *r_options) r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "optional_icons/spotlight_80x80", PROPERTY_HINT_FILE, "*.png"), "")); // Spotlight on devices with retina display r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "storyboard/use_launch_screen_storyboard"), false)); + r_options->push_back(ExportOption(PropertyInfo(Variant::INT, "storyboard/image_scale_mode", PROPERTY_HINT_ENUM, "Same as Logo,Center,Scale To Fit,Scale To Fill,Scale"), 0)); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "storyboard/custom_image@2x", PROPERTY_HINT_FILE, "*.png"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, "storyboard/custom_image@3x", PROPERTY_HINT_FILE, "*.png"), "")); + r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "storyboard/use_custom_bg_color"), false)); + r_options->push_back(ExportOption(PropertyInfo(Variant::COLOR, "storyboard/custom_bg_color"), Color())); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "launch_screens/generate_missing"), false)); @@ -277,6 +282,12 @@ void EditorExportPlatformIOS::_fix_config_file(const Ref &p_ "ad-hoc", "enterprise" }; + static const String storyboard_image_scale_mode[] = { + "center", + "scaleAspectFit", + "scaleAspectFill", + "scaleToFill" + }; String str; String strnew; str.parse_utf8((const char *)pfile.ptr(), pfile.size()); @@ -418,13 +429,25 @@ void EditorExportPlatformIOS::_fix_config_file(const Ref &p_ String value = is_on ? "" : "ASSETCATALOG_COMPILER_LAUNCHIMAGE_NAME = LaunchImage;"; strnew += lines[i].replace("$pbx_launch_image_usage_setting", value) + "\n"; } else if (lines[i].find("$launch_screen_image_mode") != -1) { - String logo_path = ProjectSettings::get_singleton()->get("application/boot_splash/image"); - bool is_on = ProjectSettings::get_singleton()->get("application/boot_splash/fullsize"); - // If custom logo is not specified, Godot does not scale default one, so we should do the same. - String value = (is_on && logo_path.length() > 0) ? "scaleAspectFit" : "center"; + int image_scale_mode = p_preset->get("storyboard/image_scale_mode"); + String value; + + switch (image_scale_mode) { + case 0: { + String logo_path = ProjectSettings::get_singleton()->get("application/boot_splash/image"); + bool is_on = ProjectSettings::get_singleton()->get("application/boot_splash/fullsize"); + // If custom logo is not specified, Godot does not scale default one, so we should do the same. + value = (is_on && logo_path.length() > 0) ? "scaleAspectFit" : "center"; + } break; + default: { + value = storyboard_image_scale_mode[image_scale_mode - 1]; + } + } + strnew += lines[i].replace("$launch_screen_image_mode", value) + "\n"; } else if (lines[i].find("$launch_screen_background_color") != -1) { - Color color = ProjectSettings::get_singleton()->get("application/boot_splash/bg_color"); + bool use_custom = p_preset->get("storyboard/use_custom_bg_color"); + Color color = use_custom ? p_preset->get("storyboard/custom_bg_color") : ProjectSettings::get_singleton()->get("application/boot_splash/bg_color"); const String value_format = "red=\"$red\" green=\"$green\" blue=\"$blue\" alpha=\"$alpha\""; Dictionary value_dictionary; @@ -637,35 +660,68 @@ Error EditorExportPlatformIOS::_export_icons(const Ref &p_pr } Error EditorExportPlatformIOS::_export_loading_screen_file(const Ref &p_preset, const String &p_dest_dir) { - Ref splash; + const String custom_launch_image_2x = p_preset->get("storyboard/custom_image@2x"); + const String custom_launch_image_3x = p_preset->get("storyboard/custom_image@3x"); - const String splash_path = ProjectSettings::get_singleton()->get("application/boot_splash/image"); + if (custom_launch_image_2x.length() > 0 && custom_launch_image_3x.length() > 0) { + Ref image; + String image_path = p_dest_dir.plus_file("splash@2x.png"); + image.instance(); + Error err = image->load(custom_launch_image_2x); - if (!splash_path.empty()) { - splash.instance(); - const Error err = splash->load(splash_path); if (err) { - splash.unref(); + image.unref(); + return err; } - } - if (splash.is_null()) { - splash = Ref(memnew(Image(boot_splash_png))); - } + if (image->save_png(image_path) != OK) { + return ERR_FILE_CANT_WRITE; + } - // Using same image for both @2x and @3x - // because Godot's own boot logo uses single image for all resolutions. - // Also not using @1x image, because devices using this image variant - // are not supported by iOS 9, which is minimal target. - const String splash_png_path_2x = p_dest_dir.plus_file("splash@2x.png"); - const String splash_png_path_3x = p_dest_dir.plus_file("splash@3x.png"); + image.unref(); + image_path = p_dest_dir.plus_file("splash@3x.png"); + image.instance(); + err = image->load(custom_launch_image_3x); - if (splash->save_png(splash_png_path_2x) != OK) { - return ERR_FILE_CANT_WRITE; - } + if (err) { + image.unref(); + return err; + } - if (splash->save_png(splash_png_path_3x) != OK) { - return ERR_FILE_CANT_WRITE; + if (image->save_png(image_path) != OK) { + return ERR_FILE_CANT_WRITE; + } + } else { + Ref splash; + + const String splash_path = ProjectSettings::get_singleton()->get("application/boot_splash/image"); + + if (!splash_path.empty()) { + splash.instance(); + const Error err = splash->load(splash_path); + if (err) { + splash.unref(); + } + } + + if (splash.is_null()) { + splash = Ref(memnew(Image(boot_splash_png))); + } + + // Using same image for both @2x and @3x + // because Godot's own boot logo uses single image for all resolutions. + // Also not using @1x image, because devices using this image variant + // are not supported by iOS 9, which is minimal target. + const String splash_png_path_2x = p_dest_dir.plus_file("splash@2x.png"); + const String splash_png_path_3x = p_dest_dir.plus_file("splash@3x.png"); + + if (splash->save_png(splash_png_path_2x) != OK) { + return ERR_FILE_CANT_WRITE; + } + + if (splash->save_png(splash_png_path_3x) != OK) { + return ERR_FILE_CANT_WRITE; + } } return OK;