iOS: Allow changing the app icon (#16020)

This commit is contained in:
Eric Warmenhoven 2023-12-20 19:22:11 -05:00 committed by GitHub
parent 9ba18d6a7c
commit 93f7bba6a5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
51 changed files with 248 additions and 163 deletions

View file

@ -1646,6 +1646,7 @@ static struct config_path_setting *populate_settings_path(
#endif
SETTING_ARRAY("log_dir", settings->paths.log_dir, true, NULL, true);
SETTING_ARRAY("app_icon", settings->paths.app_icon, true, NULL, true);
*size = count;

View file

@ -563,6 +563,7 @@ typedef struct settings
char directory_bottom_assets[PATH_MAX_LENGTH];
#endif
char log_dir[PATH_MAX_LENGTH];
char app_icon[PATH_MAX_LENGTH];
} paths;
bool modified;

View file

@ -1285,6 +1285,10 @@ MSG_HASH(
MENU_ENUM_LABEL_DEFERRED_MENU_SETTINGS_LIST,
"deferred_menu_settings_list"
)
MSG_HASH(
MENU_ENUM_LABEL_APPICON_SETTINGS,
"appicon_settings"
)
#ifdef _3DS
MSG_HASH(
MENU_ENUM_LABEL_DEFERRED_MENU_BOTTOM_SETTINGS_LIST,

View file

@ -5598,6 +5598,14 @@ MSG_HASH(
MENU_ENUM_SUBLABEL_MENU_SETTINGS,
"Change menu screen appearance settings."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_APPICON_SETTINGS,
"App Icon"
)
MSG_HASH(
MENU_ENUM_SUBLABEL_APPICON_SETTINGS,
"Change App Icon."
)
#ifdef _3DS
MSG_HASH(
MENU_ENUM_LABEL_VALUE_MENU_BOTTOM_SETTINGS,

View file

@ -335,6 +335,7 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_menu_views_settings_list, MENU_
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_quick_menu_views_settings_list, MENU_ENUM_SUBLABEL_QUICK_MENU_VIEWS_SETTINGS)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_settings_views_settings_list, MENU_ENUM_SUBLABEL_SETTINGS_VIEWS_SETTINGS)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_menu_settings_list, MENU_ENUM_SUBLABEL_MENU_SETTINGS)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_appicon_settings_list, MENU_ENUM_SUBLABEL_APPICON_SETTINGS)
#ifdef _3DS
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_menu_bottom_settings_list, MENU_ENUM_SUBLABEL_MENU_BOTTOM_SETTINGS)
#endif
@ -4821,6 +4822,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
case MENU_ENUM_LABEL_MENU_SETTINGS:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_settings_list);
break;
case MENU_ENUM_LABEL_APPICON_SETTINGS:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_appicon_settings_list);
break;
#ifdef _3DS
case MENU_ENUM_LABEL_MENU_BOTTOM_SETTINGS:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_bottom_settings_list);

View file

@ -8989,8 +8989,10 @@ unsigned menu_displaylist_build_list(
(enum menu_screensaver_effect)
settings->uints.menu_screensaver_animation;
#endif
uico_driver_state_t *uico_st = uico_state_get_ptr();
menu_displaylist_build_info_selective_t build_list[] = {
{MENU_ENUM_LABEL_APPICON_SETTINGS, PARSE_ONLY_STRING_OPTIONS, false},
{MENU_ENUM_LABEL_ONSCREEN_DISPLAY_SETTINGS, PARSE_ACTION, true},
{MENU_ENUM_LABEL_MENU_FILE_BROWSER_SETTINGS, PARSE_ACTION, true},
{MENU_ENUM_LABEL_MENU_VIEWS_SETTINGS, PARSE_ACTION, true},
@ -9032,6 +9034,9 @@ unsigned menu_displaylist_build_list(
{
switch (build_list[i].enum_idx)
{
case MENU_ENUM_LABEL_APPICON_SETTINGS:
build_list[i].checked = (uico_st->drv && uico_st->drv->set_app_icon);
break;
case MENU_ENUM_LABEL_ONSCREEN_DISPLAY_SETTINGS:
build_list[i].checked = settings->bools.settings_show_onscreen_display;
break;

View file

@ -9001,6 +9001,16 @@ static void timezone_change_handler(rarch_setting_t *setting)
}
#endif
static void appicon_change_handler(rarch_setting_t *setting)
{
uico_driver_state_t *uico_st = uico_state_get_ptr();
if (!setting)
return;
if (!uico_st->drv || !uico_st->drv->set_app_icon)
return;
uico_st->drv->set_app_icon(setting->value.target.string);
}
#ifdef _3DS
static void new3ds_speedup_change_handler(rarch_setting_t *setting)
{
@ -19504,6 +19514,36 @@ static bool setting_append_list(
START_SUB_GROUP(list, list_info, "State", &group_info, &subgroup_info, parent_group);
{
uico_driver_state_t *uico_st = uico_state_get_ptr();
struct string_list *icons;
if (uico_st->drv && uico_st->drv->get_app_icons && (icons = uico_st->drv->get_app_icons()) && icons->size)
{
char *options;
int len = 0, i = 0;
for (; i < icons->size; i++)
len += strlen(icons->elems[i].data) + 1;
options = (char*)calloc(len, sizeof(char));
string_list_join_concat(options, len, icons, "|");
CONFIG_STRING_OPTIONS(
list, list_info,
settings->paths.app_icon,
sizeof(settings->paths.app_icon),
MENU_ENUM_LABEL_APPICON_SETTINGS,
MENU_ENUM_LABEL_VALUE_APPICON_SETTINGS,
icons->elems[0].data,
options,
&group_info,
&subgroup_info,
parent_group,
general_write_handler,
general_read_handler);
SETTINGS_DATA_LIST_CURRENT_ADD_FLAGS(list, list_info, SD_FLAG_IS_DRIVER);
(*list)[list_info->index - 1].action_ok = setting_action_ok_uint;
(*list)[list_info->index - 1].change_handler = appicon_change_handler;
}
}
CONFIG_BOOL(
list, list_info,
&settings->bools.pause_nonactive,

View file

@ -1751,6 +1751,7 @@ enum msg_hash_enums
MENU_LABEL(QUICK_MENU_VIEWS_SETTINGS),
MENU_LABEL(SETTINGS_VIEWS_SETTINGS),
MENU_LABEL(MENU_SETTINGS),
MENU_LABEL(APPICON_SETTINGS),
#ifdef _3DS
MENU_LABEL(MENU_BOTTOM_SETTINGS),
#endif

View file

@ -1540,7 +1540,8 @@
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ARCHS = "$(ARCHS_STANDARD)";
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_APPICON_NAME = Default;
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
@ -1614,7 +1615,8 @@
buildSettings = {
ALWAYS_EMBED_SWIFT_STANDARD_LIBRARIES = YES;
ARCHS = "$(ARCHS_STANDARD)";
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
ASSETCATALOG_COMPILER_APPICON_NAME = Default;
ASSETCATALOG_COMPILER_INCLUDE_ALL_APPICON_ASSETS = YES;
CLANG_CXX_LANGUAGE_STANDARD = "c++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;

View file

@ -1,158 +0,0 @@
{
"images" : [
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-20-3.png",
"scale" : "2x"
},
{
"size" : "20x20",
"idiom" : "iphone",
"filename" : "Icon-76-3.png",
"scale" : "3x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-29-1.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-29-2.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-29-3.png",
"scale" : "3x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-40-2.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-40-3.png",
"scale" : "3x"
},
{
"size" : "57x57",
"idiom" : "iphone",
"filename" : "Icon-57-1.png",
"scale" : "1x"
},
{
"size" : "57x57",
"idiom" : "iphone",
"filename" : "Icon-57-2.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-60-2.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-60-3.png",
"scale" : "3x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-20-4.png",
"scale" : "1x"
},
{
"size" : "20x20",
"idiom" : "ipad",
"filename" : "Icon-20-2.png",
"scale" : "2x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-29-1.png",
"scale" : "1x"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-29-2.png",
"scale" : "2x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-40-1.png",
"scale" : "1x"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-40-2.png",
"scale" : "2x"
},
{
"size" : "50x50",
"idiom" : "ipad",
"filename" : "Icon-50-1.png",
"scale" : "1x"
},
{
"size" : "50x50",
"idiom" : "ipad",
"filename" : "Icon-50-2.png",
"scale" : "2x"
},
{
"size" : "72x72",
"idiom" : "ipad",
"filename" : "Icon-72-1.png",
"scale" : "1x"
},
{
"size" : "72x72",
"idiom" : "ipad",
"filename" : "Icon-72-2.png",
"scale" : "2x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-76-1.png",
"scale" : "1x"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-76-2.png",
"scale" : "2x"
},
{
"size" : "83.5x83.5",
"idiom" : "ipad",
"filename" : "Icon-83.5-2.png",
"scale" : "2x"
},
{
"size" : "1024x1024",
"idiom" : "ios-marketing",
"filename" : "Icon-83.5-3.png",
"scale" : "1x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.3 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 7.8 KiB

View file

@ -0,0 +1,14 @@
{
"images" : [
{
"filename" : "RetroArch_Arcade_1.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 66 KiB

View file

@ -0,0 +1,14 @@
{
"images" : [
{
"filename" : "RetroArch_Arcade_2.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

View file

@ -1,6 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
"author" : "xcode",
"version" : 1
}
}
}

View file

@ -0,0 +1,14 @@
{
"images" : [
{
"filename" : "Icon-83.5-3.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

View file

@ -0,0 +1,14 @@
{
"images" : [
{
"filename" : "Retroarch.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 783 KiB

View file

@ -0,0 +1,14 @@
{
"images" : [
{
"filename" : "Retroarch_Gruvbox.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 912 KiB

View file

@ -0,0 +1,14 @@
{
"images" : [
{
"filename" : "Retroarch_Light.png",
"idiom" : "universal",
"platform" : "ios",
"size" : "1024x1024"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 628 KiB

View file

@ -7559,6 +7559,7 @@ bool retroarch_main_init(int argc, char *argv[])
#endif
);
#endif
ui_companion_driver_init_first();
drivers_init(settings, DRIVERS_CMD_ALL, 0, verbosity_enabled);
#ifdef HAVE_COMMAND
input_driver_deinit_command(input_st);

View file

@ -1111,6 +1111,8 @@ ui_companion_driver_t ui_companion_cocoa = {
ui_companion_cocoa_get_main_window,
NULL, /* log_msg */
NULL, /* is_active */
NULL, /* get_app_icons */
NULL, /* set_app_icon */
&ui_browser_window_cocoa,
&ui_msg_window_cocoa,
&ui_window_cocoa,

View file

@ -41,6 +41,7 @@
#endif
#import <AVFoundation/AVFoundation.h>
#import <CoreFoundation/CoreFoundation.h>
#import <MetricKit/MetricKit.h>
#import <MetricKit/MXMetricManager.h>
@ -56,6 +57,46 @@ static CFRunLoopObserverRef iterate_observer;
static void ui_companion_cocoatouch_event_command(
void *data, enum event_command cmd) { }
static struct string_list *ui_companion_cocoatouch_get_app_icons(void)
{
static struct string_list *list = NULL;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
union string_list_elem_attr attr;
attr.i = 0;
NSDictionary *iconfiles = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleIcons"];
NSString *primary;
#if TARGET_OS_TV
primary = iconfiles[@"CFBundlePrimaryIcon"];
#else
primary = iconfiles[@"CFBundlePrimaryIcon"][@"CFBundleIconName"];
#endif
list = string_list_new();
string_list_append(list, [primary cStringUsingEncoding:kCFStringEncodingUTF8], attr);
NSArray<NSString *> *alts;
#if TARGET_OS_TV
alts = iconfiles[@"CFBundleAlternateIcons"];
#else
alts = [iconfiles[@"CFBundleAlternateIcons"] allKeys];
#endif
NSArray<NSString *> *sorted = [alts sortedArrayUsingSelector:@selector(localizedCaseInsensitiveCompare:)];
for (NSString *str in sorted)
string_list_append(list, [str cStringUsingEncoding:kCFStringEncodingUTF8], attr);
});
return list;
}
static void ui_companion_cocoatouch_set_app_icon(const char *iconName)
{
NSString *str;
if (!string_is_equal(iconName, "Default"))
str = [NSString stringWithCString:iconName encoding:NSUTF8StringEncoding];
[[UIApplication sharedApplication] setAlternateIconName:str completionHandler:nil];
}
static void rarch_draw_observer(CFRunLoopObserverRef observer,
CFRunLoopActivity activity, void *info)
{
@ -457,6 +498,22 @@ enum
}
}
- (NSData *)pngForIcon:(NSString *)iconName
{
UIImage *img;
NSData *png;
img = [UIImage imageNamed:iconName];
if (!img)
NSLog(@"could not load %@\n", iconName);
else
{
png = UIImagePNGRepresentation(img);
if (!png)
NSLog(@"could not get png for %@\n", iconName);
}
return png;
}
- (void)applicationDidFinishLaunching:(UIApplication *)application
{
char arguments[] = "retroarch";
@ -599,6 +656,26 @@ enum
@end
ui_companion_driver_t ui_companion_cocoatouch = {
NULL, /* init */
NULL, /* deinit */
NULL, /* toggle */
ui_companion_cocoatouch_event_command,
NULL, /* notify_refresh */
NULL, /* msg_queue_push */
NULL, /* render_messagebox */
NULL, /* get_main_window */
NULL, /* log_msg */
NULL, /* is_active */
ui_companion_cocoatouch_get_app_icons,
ui_companion_cocoatouch_set_app_icon,
NULL, /* browser_window */
NULL, /* msg_window */
NULL, /* window */
NULL, /* application */
"cocoatouch",
};
int main(int argc, char *argv[])
{
#if TARGET_OS_IOS

View file

@ -4940,6 +4940,8 @@ ui_companion_driver_t ui_companion_qt = {
NULL,
ui_companion_qt_log_msg,
ui_companion_qt_is_active,
NULL, /* get_app_icons */
NULL, /* set_app_icon */
&ui_browser_window_qt,
&ui_msg_window_qt,
&ui_window_qt,

View file

@ -336,6 +336,8 @@ ui_companion_driver_t ui_companion_win32 = {
NULL,
NULL, /* log_msg */
NULL, /* is_active */
NULL, /* get_app_icons */
NULL, /* set_app_icon */
&ui_browser_window_win32,
&ui_msg_window_win32,
&ui_window_win32,

View file

@ -38,6 +38,8 @@ static ui_companion_driver_t ui_companion_null = {
NULL, /* get_main_window */
NULL, /* log_msg */
NULL, /* is_active */
NULL, /* get_app_icons */
NULL, /* set_app_icon */
NULL, /* browser_window */
NULL, /* msg_window */
NULL, /* window */
@ -51,6 +53,9 @@ static const ui_companion_driver_t *ui_companion_drivers[] = {
#endif
#if defined(OSX)
&ui_companion_cocoa,
#endif
#if defined(IOS)
&ui_companion_cocoatouch,
#endif
&ui_companion_null,
NULL

View file

@ -22,6 +22,7 @@
#include <boolean.h>
#include <retro_common_api.h>
#include <lists/file_list.h>
#include <lists/string_list.h>
#ifdef HAVE_CONFIG_H
#include "../config.h"
@ -130,6 +131,8 @@ typedef struct ui_companion_driver
void *(*get_main_window)(void *data);
void (*log_msg)(void *data, const char *msg);
bool (*is_active)(void *data);
struct string_list *(*get_app_icons)(void);
void (*set_app_icon)(const char *icon);
ui_browser_window_t *browser_window;
ui_msg_window_t *msg_window;
ui_window_t *window;
@ -181,6 +184,7 @@ void ui_companion_driver_toggle(
uico_driver_state_t *uico_state_get_ptr(void);
extern ui_companion_driver_t ui_companion_cocoa;
extern ui_companion_driver_t ui_companion_cocoatouch;
extern ui_companion_driver_t ui_companion_qt;
extern ui_companion_driver_t ui_companion_win32;