Merge pull request #97517 from syntaxerror247/android-themed-icon

Add support for Android Themed Icons (monochrome)
This commit is contained in:
Rémi Verschelde 2024-09-27 14:57:34 +02:00 committed by GitHub
commit 76a135926a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 45 additions and 6 deletions

View File

@ -102,6 +102,9 @@
<member name="launcher_icons/adaptive_foreground_432x432" type="String" setter="" getter=""> <member name="launcher_icons/adaptive_foreground_432x432" type="String" setter="" getter="">
Foreground layer of the application adaptive icon file. See [url=https://developer.android.com/develop/ui/views/launch/icon_design_adaptive#design-adaptive-icons]Design adaptive icons[/url]. Foreground layer of the application adaptive icon file. See [url=https://developer.android.com/develop/ui/views/launch/icon_design_adaptive#design-adaptive-icons]Design adaptive icons[/url].
</member> </member>
<member name="launcher_icons/adaptive_monochrome_432x432" type="String" setter="" getter="">
Monochrome layer of the application adaptive icon file. See [url=https://developer.android.com/develop/ui/views/launch/icon_design_adaptive#design-adaptive-icons]Design adaptive icons[/url].
</member>
<member name="launcher_icons/main_192x192" type="String" setter="" getter=""> <member name="launcher_icons/main_192x192" type="String" setter="" getter="">
Application icon file. If left empty, it will fallback to [member ProjectSettings.application/config/icon]. Application icon file. If left empty, it will fallback to [member ProjectSettings.application/config/icon].
</member> </member>

View File

@ -222,6 +222,7 @@ static const int icon_densities_count = 6;
static const char *launcher_icon_option = PNAME("launcher_icons/main_192x192"); static const char *launcher_icon_option = PNAME("launcher_icons/main_192x192");
static const char *launcher_adaptive_icon_foreground_option = PNAME("launcher_icons/adaptive_foreground_432x432"); static const char *launcher_adaptive_icon_foreground_option = PNAME("launcher_icons/adaptive_foreground_432x432");
static const char *launcher_adaptive_icon_background_option = PNAME("launcher_icons/adaptive_background_432x432"); static const char *launcher_adaptive_icon_background_option = PNAME("launcher_icons/adaptive_background_432x432");
static const char *launcher_adaptive_icon_monochrome_option = PNAME("launcher_icons/adaptive_monochrome_432x432");
static const LauncherIcon launcher_icons[icon_densities_count] = { static const LauncherIcon launcher_icons[icon_densities_count] = {
{ "res/mipmap-xxxhdpi-v4/icon.png", 192 }, { "res/mipmap-xxxhdpi-v4/icon.png", 192 },
@ -250,6 +251,15 @@ static const LauncherIcon launcher_adaptive_icon_backgrounds[icon_densities_coun
{ "res/mipmap/icon_background.png", 432 } { "res/mipmap/icon_background.png", 432 }
}; };
static const LauncherIcon launcher_adaptive_icon_monochromes[icon_densities_count] = {
{ "res/mipmap-xxxhdpi-v4/icon_monochrome.png", 432 },
{ "res/mipmap-xxhdpi-v4/icon_monochrome.png", 324 },
{ "res/mipmap-xhdpi-v4/icon_monochrome.png", 216 },
{ "res/mipmap-hdpi-v4/icon_monochrome.png", 162 },
{ "res/mipmap-mdpi-v4/icon_monochrome.png", 108 },
{ "res/mipmap/icon_monochrome.png", 432 }
};
static const int EXPORT_FORMAT_APK = 0; static const int EXPORT_FORMAT_APK = 0;
static const int EXPORT_FORMAT_AAB = 1; static const int EXPORT_FORMAT_AAB = 1;
@ -1644,12 +1654,13 @@ void EditorExportPlatformAndroid::_process_launcher_icons(const String &p_file_n
} }
} }
void EditorExportPlatformAndroid::load_icon_refs(const Ref<EditorExportPreset> &p_preset, Ref<Image> &icon, Ref<Image> &foreground, Ref<Image> &background) { void EditorExportPlatformAndroid::load_icon_refs(const Ref<EditorExportPreset> &p_preset, Ref<Image> &icon, Ref<Image> &foreground, Ref<Image> &background, Ref<Image> &monochrome) {
String project_icon_path = GLOBAL_GET("application/config/icon"); String project_icon_path = GLOBAL_GET("application/config/icon");
icon.instantiate(); icon.instantiate();
foreground.instantiate(); foreground.instantiate();
background.instantiate(); background.instantiate();
monochrome.instantiate();
// Regular icon: user selection -> project icon -> default. // Regular icon: user selection -> project icon -> default.
String path = static_cast<String>(p_preset->get(launcher_icon_option)).strip_edges(); String path = static_cast<String>(p_preset->get(launcher_icon_option)).strip_edges();
@ -1677,12 +1688,20 @@ void EditorExportPlatformAndroid::load_icon_refs(const Ref<EditorExportPreset> &
print_verbose("Loading adaptive background icon from " + path); print_verbose("Loading adaptive background icon from " + path);
ImageLoader::load_image(path, background); ImageLoader::load_image(path, background);
} }
// Adaptive monochrome: user selection -> default.
path = static_cast<String>(p_preset->get(launcher_adaptive_icon_monochrome_option)).strip_edges();
if (!path.is_empty()) {
print_verbose("Loading adaptive monochrome icon from " + path);
ImageLoader::load_image(path, background);
}
} }
void EditorExportPlatformAndroid::_copy_icons_to_gradle_project(const Ref<EditorExportPreset> &p_preset, void EditorExportPlatformAndroid::_copy_icons_to_gradle_project(const Ref<EditorExportPreset> &p_preset,
const Ref<Image> &p_main_image, const Ref<Image> &p_main_image,
const Ref<Image> &p_foreground, const Ref<Image> &p_foreground,
const Ref<Image> &p_background) { const Ref<Image> &p_background,
const Ref<Image> &p_monochrome) {
String gradle_build_dir = ExportTemplateManager::get_android_build_directory(p_preset); String gradle_build_dir = ExportTemplateManager::get_android_build_directory(p_preset);
// Prepare images to be resized for the icons. If some image ends up being uninitialized, // Prepare images to be resized for the icons. If some image ends up being uninitialized,
@ -1711,6 +1730,14 @@ void EditorExportPlatformAndroid::_copy_icons_to_gradle_project(const Ref<Editor
launcher_adaptive_icon_backgrounds[i].dimensions, data); launcher_adaptive_icon_backgrounds[i].dimensions, data);
store_file_at_path(gradle_build_dir.path_join(launcher_adaptive_icon_backgrounds[i].export_path), data); store_file_at_path(gradle_build_dir.path_join(launcher_adaptive_icon_backgrounds[i].export_path), data);
} }
if (p_monochrome.is_valid() && !p_monochrome->is_empty()) {
print_verbose("Processing launcher adaptive icon p_monochrome for dimension " + itos(launcher_adaptive_icon_monochromes[i].dimensions) + " into " + launcher_adaptive_icon_monochromes[i].export_path);
Vector<uint8_t> data;
_process_launcher_icons(launcher_adaptive_icon_monochromes[i].export_path, p_monochrome,
launcher_adaptive_icon_monochromes[i].dimensions, data);
store_file_at_path(gradle_build_dir.path_join(launcher_adaptive_icon_monochromes[i].export_path), data);
}
} }
} }
@ -1875,6 +1902,7 @@ void EditorExportPlatformAndroid::get_export_options(List<ExportOption> *r_optio
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_icon_option, PROPERTY_HINT_FILE, "*.png"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_icon_option, PROPERTY_HINT_FILE, "*.png"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_adaptive_icon_foreground_option, PROPERTY_HINT_FILE, "*.png"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_adaptive_icon_foreground_option, PROPERTY_HINT_FILE, "*.png"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_adaptive_icon_background_option, PROPERTY_HINT_FILE, "*.png"), "")); r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_adaptive_icon_background_option, PROPERTY_HINT_FILE, "*.png"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, launcher_adaptive_icon_monochrome_option, PROPERTY_HINT_FILE, "*.png"), ""));
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "graphics/opengl_debug"), false)); r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "graphics/opengl_debug"), false));
@ -3035,8 +3063,9 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
Ref<Image> main_image; Ref<Image> main_image;
Ref<Image> foreground; Ref<Image> foreground;
Ref<Image> background; Ref<Image> background;
Ref<Image> monochrome;
load_icon_refs(p_preset, main_image, foreground, background); load_icon_refs(p_preset, main_image, foreground, background, monochrome);
Vector<uint8_t> command_line_flags; Vector<uint8_t> command_line_flags;
// Write command line flags into the command_line_flags variable. // Write command line flags into the command_line_flags variable.
@ -3107,7 +3136,7 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Unable to overwrite res/*.xml files with project name.")); add_message(EXPORT_MESSAGE_ERROR, TTR("Export"), TTR("Unable to overwrite res/*.xml files with project name."));
} }
// Copies the project icon files into the appropriate Gradle project directory. // Copies the project icon files into the appropriate Gradle project directory.
_copy_icons_to_gradle_project(p_preset, main_image, foreground, background); _copy_icons_to_gradle_project(p_preset, main_image, foreground, background, monochrome);
// Write an AndroidManifest.xml file into the Gradle project directory. // Write an AndroidManifest.xml file into the Gradle project directory.
_write_tmp_manifest(p_preset, p_give_internet, p_debug); _write_tmp_manifest(p_preset, p_give_internet, p_debug);
@ -3446,6 +3475,11 @@ Error EditorExportPlatformAndroid::export_project_helper(const Ref<EditorExportP
_process_launcher_icons(file, background, launcher_adaptive_icon_backgrounds[i].dimensions, data); _process_launcher_icons(file, background, launcher_adaptive_icon_backgrounds[i].dimensions, data);
} }
} }
if (monochrome.is_valid() && !monochrome->is_empty()) {
if (file == launcher_adaptive_icon_monochromes[i].export_path) {
_process_launcher_icons(file, monochrome, launcher_adaptive_icon_monochromes[i].dimensions, data);
}
}
} }
} }

View File

@ -167,12 +167,13 @@ class EditorExportPlatformAndroid : public EditorExportPlatform {
void _process_launcher_icons(const String &p_file_name, const Ref<Image> &p_source_image, int dimension, Vector<uint8_t> &p_data); void _process_launcher_icons(const String &p_file_name, const Ref<Image> &p_source_image, int dimension, Vector<uint8_t> &p_data);
void load_icon_refs(const Ref<EditorExportPreset> &p_preset, Ref<Image> &icon, Ref<Image> &foreground, Ref<Image> &background); void load_icon_refs(const Ref<EditorExportPreset> &p_preset, Ref<Image> &icon, Ref<Image> &foreground, Ref<Image> &background, Ref<Image> &monochrome);
void _copy_icons_to_gradle_project(const Ref<EditorExportPreset> &p_preset, void _copy_icons_to_gradle_project(const Ref<EditorExportPreset> &p_preset,
const Ref<Image> &p_main_image, const Ref<Image> &p_main_image,
const Ref<Image> &p_foreground, const Ref<Image> &p_foreground,
const Ref<Image> &p_background); const Ref<Image> &p_background,
const Ref<Image> &p_monochrome);
static void _create_editor_debug_keystore_if_needed(); static void _create_editor_debug_keystore_if_needed();

View File

@ -2,4 +2,5 @@
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android"> <adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@mipmap/icon_background"/> <background android:drawable="@mipmap/icon_background"/>
<foreground android:drawable="@mipmap/icon_foreground"/> <foreground android:drawable="@mipmap/icon_foreground"/>
<monochrome android:drawable="@mipmap/icon_monochrome"/>
</adaptive-icon> </adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.5 KiB