1
0
mirror of https://github.com/libretro/RetroArch synced 2025-02-19 12:41:00 +00:00

(RGUI) Add optional 'toggle switch' icons

This commit is contained in:
jdgleaver 2020-07-27 14:43:54 +01:00
parent 7f1cd52d65
commit fba4a8e837
10 changed files with 287 additions and 53 deletions

@ -571,6 +571,7 @@ static const bool rgui_shadows = false;
static const unsigned rgui_particle_effect = RGUI_PARTICLE_EFFECT_NONE;
#define DEFAULT_RGUI_PARTICLE_EFFECT_SPEED 1.0f
static const bool rgui_extended_ascii = false;
#define DEFAULT_RGUI_SWITCH_ICONS true
#endif
#ifdef HAVE_MENU

@ -1635,6 +1635,7 @@ static struct config_bool_setting *populate_settings_bool(
SETTING_BOOL("rgui_inline_thumbnails", &settings->bools.menu_rgui_inline_thumbnails, true, rgui_inline_thumbnails, false);
SETTING_BOOL("rgui_swap_thumbnails", &settings->bools.menu_rgui_swap_thumbnails, true, rgui_swap_thumbnails, false);
SETTING_BOOL("rgui_extended_ascii", &settings->bools.menu_rgui_extended_ascii, true, rgui_extended_ascii, false);
SETTING_BOOL("rgui_switch_icons", &settings->bools.menu_rgui_switch_icons, true, DEFAULT_RGUI_SWITCH_ICONS, false);
#endif
#ifdef HAVE_XMB
SETTING_BOOL("xmb_shadows_enable", &settings->bools.menu_xmb_shadows_enable, true, DEFAULT_XMB_SHADOWS_ENABLE, false);

@ -219,6 +219,7 @@ typedef struct settings
bool menu_rgui_inline_thumbnails;
bool menu_rgui_swap_thumbnails;
bool menu_rgui_extended_ascii;
bool menu_rgui_switch_icons;
bool menu_xmb_shadows_enable;
bool menu_xmb_vertical_thumbnails;
bool menu_content_show_settings;

@ -3894,6 +3894,10 @@ MSG_HASH(
MENU_ENUM_LABEL_MENU_RGUI_EXTENDED_ASCII,
"rgui_extended_ascii"
)
MSG_HASH(
MENU_ENUM_LABEL_MENU_RGUI_SWITCH_ICONS,
"rgui_switch_icons"
)
MSG_HASH(
MENU_ENUM_LABEL_CONTENT_SHOW_REWIND,
"menu_show_rewind_settings"

@ -7624,6 +7624,14 @@ MSG_HASH(
MENU_ENUM_SUBLABEL_MENU_RGUI_EXTENDED_ASCII,
"Enable display of non-standard ASCII characters. Required for compatibility with certain non-English Western languages. Has a moderate performance impact."
)
MSG_HASH(
MENU_ENUM_LABEL_VALUE_MENU_RGUI_SWITCH_ICONS,
"Show Switch Icons"
)
MSG_HASH(
MENU_ENUM_SUBLABEL_MENU_RGUI_SWITCH_ICONS,
"Use icons instead of ON/OFF text to represent 'toggle switch' menu settings entries."
)
/* RGUI: Settings Options */

@ -852,6 +852,7 @@ DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_playlist_use_old_format,
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_playlist_compression, MENU_ENUM_SUBLABEL_PLAYLIST_COMPRESSION)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_menu_rgui_full_width_layout, MENU_ENUM_SUBLABEL_MENU_RGUI_FULL_WIDTH_LAYOUT)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_menu_rgui_extended_ascii, MENU_ENUM_SUBLABEL_MENU_RGUI_EXTENDED_ASCII)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_menu_rgui_switch_icons, MENU_ENUM_SUBLABEL_MENU_RGUI_SWITCH_ICONS)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_thumbnails_updater_list, MENU_ENUM_SUBLABEL_THUMBNAILS_UPDATER_LIST)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_pl_thumbnails_updater_list, MENU_ENUM_SUBLABEL_PL_THUMBNAILS_UPDATER_LIST)
DEFAULT_SUBLABEL_MACRO(action_bind_sublabel_help_send_debug_info, MENU_ENUM_SUBLABEL_HELP_SEND_DEBUG_INFO)
@ -3822,6 +3823,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
case MENU_ENUM_LABEL_MENU_RGUI_EXTENDED_ASCII:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_rgui_extended_ascii);
break;
case MENU_ENUM_LABEL_MENU_RGUI_SWITCH_ICONS:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_rgui_switch_icons);
break;
case MENU_ENUM_LABEL_THUMBNAILS_UPDATER_LIST:
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_thumbnails_updater_list);
break;

@ -550,6 +550,20 @@ typedef struct
float d;
} rgui_particle_t;
/* Defines all possible entry value types
* > Note: These are not necessarily 'values',
* but they correspond to the object drawn in
* the 'value' location when rendering
* menu lists */
enum rgui_entry_value_type
{
RGUI_ENTRY_VALUE_NONE = 0,
RGUI_ENTRY_VALUE_TEXT,
RGUI_ENTRY_VALUE_SWITCH_ON,
RGUI_ENTRY_VALUE_SWITCH_OFF,
RGUI_ENTRY_VALUE_CHECKMARK
};
typedef struct
{
bool bg_modified;
@ -625,7 +639,13 @@ enum rgui_symbol_type
RGUI_SYMBOL_BATTERY_60,
RGUI_SYMBOL_BATTERY_40,
RGUI_SYMBOL_BATTERY_20,
RGUI_SYMBOL_CHECKMARK
RGUI_SYMBOL_CHECKMARK,
RGUI_SYMBOL_SWITCH_ON_LEFT,
RGUI_SYMBOL_SWITCH_ON_CENTRE,
RGUI_SYMBOL_SWITCH_ON_RIGHT,
RGUI_SYMBOL_SWITCH_OFF_LEFT,
RGUI_SYMBOL_SWITCH_OFF_CENTRE,
RGUI_SYMBOL_SWITCH_OFF_RIGHT
};
/* All custom symbols must have dimensions
@ -789,6 +809,78 @@ static const uint8_t rgui_symbol_data_checkmark[FONT_WIDTH * FONT_HEIGHT] = {
0, 1, 1, 0, 0,
0, 0, 0, 0, 0};
static const uint8_t rgui_symbol_data_switch_on_left[FONT_WIDTH * FONT_HEIGHT] = {
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 1, 1, 1, 1,
1, 1, 1, 1, 1,
0, 1, 1, 1, 1,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0, /* Baseline */
0, 0, 0, 0, 0,
0, 0, 0, 0, 0};
static const uint8_t rgui_symbol_data_switch_on_centre[FONT_WIDTH * FONT_HEIGHT] = {
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
1, 1, 1, 1, 0,
1, 1, 1, 1, 0,
1, 1, 1, 1, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0, /* Baseline */
0, 0, 0, 0, 0,
0, 0, 0, 0, 0};
static const uint8_t rgui_symbol_data_switch_on_right[FONT_WIDTH * FONT_HEIGHT] = {
0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
1, 1, 1, 1, 1,
0, 1, 1, 1, 0, /* Baseline */
0, 0, 0, 0, 0,
0, 0, 0, 0, 0};
static const uint8_t rgui_symbol_data_switch_off_left[FONT_WIDTH * FONT_HEIGHT] = {
0, 0, 0, 0, 0,
0, 1, 1, 1, 0,
1, 0, 0, 0, 1,
1, 0, 0, 0, 1,
1, 0, 0, 0, 1,
1, 0, 0, 0, 1,
1, 0, 0, 0, 1,
0, 1, 1, 1, 0, /* Baseline */
0, 0, 0, 0, 0,
0, 0, 0, 0, 0};
static const uint8_t rgui_symbol_data_switch_off_centre[FONT_WIDTH * FONT_HEIGHT] = {
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 1, 1, 1, 1,
0, 1, 0, 0, 0,
0, 1, 1, 1, 1,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0, /* Baseline */
0, 0, 0, 0, 0,
0, 0, 0, 0, 0};
static const uint8_t rgui_symbol_data_switch_off_right[FONT_WIDTH * FONT_HEIGHT] = {
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0,
1, 1, 1, 1, 0,
0, 0, 0, 0, 1,
1, 1, 1, 1, 0,
0, 0, 0, 0, 0,
0, 0, 0, 0, 0, /* Baseline */
0, 0, 0, 0, 0,
0, 0, 0, 0, 0};
/* ==============================
* Custom Symbols (glyphs) END
* ============================== */
@ -2638,6 +2730,18 @@ static const uint8_t *rgui_get_symbol_data(enum rgui_symbol_type symbol)
return rgui_symbol_data_battery_20;
case RGUI_SYMBOL_CHECKMARK:
return rgui_symbol_data_checkmark;
case RGUI_SYMBOL_SWITCH_ON_LEFT:
return rgui_symbol_data_switch_on_left;
case RGUI_SYMBOL_SWITCH_ON_CENTRE:
return rgui_symbol_data_switch_on_centre;
case RGUI_SYMBOL_SWITCH_ON_RIGHT:
return rgui_symbol_data_switch_on_right;
case RGUI_SYMBOL_SWITCH_OFF_LEFT:
return rgui_symbol_data_switch_off_left;
case RGUI_SYMBOL_SWITCH_OFF_CENTRE:
return rgui_symbol_data_switch_off_centre;
case RGUI_SYMBOL_SWITCH_OFF_RIGHT:
return rgui_symbol_data_switch_off_right;
default:
break;
}
@ -3228,6 +3332,58 @@ static void rgui_render_osk(
}
}
static void rgui_render_toggle_switch(unsigned fb_width, int x, int y,
bool on, uint16_t color, uint16_t shadow_color)
{
int x_current = x;
/* Toggle switch is just 3 adjacent symbols
* > Note that we indent the left/right symbols
* by 1 pixel, to avoid the gap that is normally
* present between symbols/characters */
blit_symbol(fb_width, x_current + 1, y,
on ? RGUI_SYMBOL_SWITCH_ON_LEFT : RGUI_SYMBOL_SWITCH_OFF_LEFT,
color, shadow_color);
x_current += FONT_WIDTH_STRIDE;
blit_symbol(fb_width, x_current, y,
on ? RGUI_SYMBOL_SWITCH_ON_CENTRE : RGUI_SYMBOL_SWITCH_OFF_CENTRE,
color, shadow_color);
x_current += FONT_WIDTH_STRIDE;
blit_symbol(fb_width, x_current - 1, y,
on ? RGUI_SYMBOL_SWITCH_ON_RIGHT : RGUI_SYMBOL_SWITCH_OFF_RIGHT,
color, shadow_color);
}
static enum rgui_entry_value_type rgui_get_entry_value_type(
const char *entry_value, bool entry_checked,
bool switch_icons_enabled)
{
enum rgui_entry_value_type value_type = RGUI_ENTRY_VALUE_NONE;
if (!string_is_empty(entry_value))
{
value_type = RGUI_ENTRY_VALUE_TEXT;
if (switch_icons_enabled)
{
/* Toggle switch off */
if (string_is_equal(entry_value, msg_hash_to_str(MENU_ENUM_LABEL_DISABLED)) ||
string_is_equal(entry_value, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)))
value_type = RGUI_ENTRY_VALUE_SWITCH_OFF;
/* Toggle switch on */
else if (string_is_equal(entry_value, msg_hash_to_str(MENU_ENUM_LABEL_ENABLED)) ||
string_is_equal(entry_value, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_ON)))
value_type = RGUI_ENTRY_VALUE_SWITCH_ON;
}
}
else if (entry_checked)
value_type = RGUI_ENTRY_VALUE_CHECKMARK;
return value_type;
}
#if defined(GEKKO)
/* Need to forward declare this for the Wii build
* (I'm not going to reorder the functions and mess
@ -3262,6 +3418,7 @@ static void rgui_render(void *data,
bool use_smooth_ticker = settings->bools.menu_ticker_smooth;
bool rgui_swap_thumbnails = settings->bools.menu_rgui_swap_thumbnails;
bool rgui_full_width_layout = settings->bools.menu_rgui_full_width_layout;
bool rgui_switch_icons = settings->bools.menu_rgui_switch_icons;
bool menu_show_sublabels = settings->bools.menu_show_sublabels;
bool video_fullscreen = settings->bools.video_fullscreen;
bool menu_mouse_enable = settings->bools.menu_mouse_enable;
@ -3656,12 +3813,13 @@ static void rgui_render(void *data,
char entry_title_buf[255];
char type_str_buf[255];
menu_entry_t entry;
const char *entry_label = NULL;
const char *entry_value = NULL;
size_t entry_title_max_len = 0;
unsigned entry_value_len = 0;
bool entry_selected = (i == selection);
uint16_t entry_color = entry_selected ?
const char *entry_label = NULL;
const char *entry_value = NULL;
size_t entry_title_max_len = 0;
unsigned entry_value_len = 0;
enum rgui_entry_value_type entry_value_type = RGUI_ENTRY_VALUE_NONE;
bool entry_selected = (i == selection);
uint16_t entry_color = entry_selected ?
rgui->colors.hover_color : rgui->colors.normal_color;
if (i > (selection + 100))
@ -3721,23 +3879,45 @@ static void rgui_render(void *data,
entry_title_max_len -= (thumbnail_width / FONT_WIDTH_STRIDE) + 1;
}
/* Determine whether entry has a value component */
if (!string_is_empty(entry_value))
{
if (rgui_full_width_layout)
{
/* Resize fields according to actual length of value string */
entry_value_len = (unsigned)strlen(entry_value);
entry_value_len = (entry_value_len
> rgui_term_layout.value_maxlen)
? rgui_term_layout.value_maxlen
: entry_value_len;
}
else /* Use classic fixed width layout */
entry_value_len = entry.spacing;
/* Get 'type' of entry value component */
entry_value_type = rgui_get_entry_value_type(
entry_value, entry.checked, rgui_switch_icons);
/* Update width of entry title field */
entry_title_max_len -= entry_value_len + 2;
switch (entry_value_type)
{
case RGUI_ENTRY_VALUE_TEXT:
/* Resize fields according to actual length
* of value string */
if (rgui_full_width_layout)
{
entry_value_len = (unsigned)strlen(entry_value);
entry_value_len = (entry_value_len
> rgui_term_layout.value_maxlen) ?
rgui_term_layout.value_maxlen :
entry_value_len;
}
/* Use classic fixed width layout */
else
entry_value_len = entry.spacing;
/* Update width of entry title field */
entry_title_max_len -= entry_value_len + 2;
break;
case RGUI_ENTRY_VALUE_SWITCH_ON:
case RGUI_ENTRY_VALUE_SWITCH_OFF:
/* Switch icon is 3 characters wide
* (if using classic fixed width layout,
* set maximum width to ensure icon is
* aligned with left hand edge of values
* column) */
entry_value_len = rgui_full_width_layout ?
3 : RGUI_ENTRY_VALUE_MAXLEN;
/* Update width of entry title field */
entry_title_max_len -= entry_value_len + 2;
break;
default:
break;
}
/* Format entry title string */
@ -3769,41 +3949,59 @@ static void rgui_render(void *data,
entry_color, rgui->colors.shadow_color);
/* Print entry value, if required */
if (entry_value_len > 0)
switch (entry_value_type)
{
/* Format entry value string */
if (use_smooth_ticker)
{
ticker_smooth.field_width = entry_value_len * FONT_WIDTH_STRIDE;
ticker_smooth.src_str = entry_value;
ticker_smooth.dst_str = type_str_buf;
ticker_smooth.dst_str_len = sizeof(type_str_buf);
ticker_smooth.x_offset = &ticker_x_offset;
case RGUI_ENTRY_VALUE_TEXT:
/* Format entry value string */
if (use_smooth_ticker)
{
ticker_smooth.field_width = entry_value_len * FONT_WIDTH_STRIDE;
ticker_smooth.src_str = entry_value;
ticker_smooth.dst_str = type_str_buf;
ticker_smooth.dst_str_len = sizeof(type_str_buf);
ticker_smooth.x_offset = &ticker_x_offset;
gfx_animation_ticker_smooth(&ticker_smooth);
}
else
{
ticker.s = type_str_buf;
ticker.len = entry_value_len;
ticker.str = entry_value;
gfx_animation_ticker_smooth(&ticker_smooth);
}
else
{
ticker.s = type_str_buf;
ticker.len = entry_value_len;
ticker.str = entry_value;
gfx_animation_ticker(&ticker);
}
gfx_animation_ticker(&ticker);
}
/* Print entry value */
blit_line(rgui,
fb_width,
ticker_x_offset + term_end_x - ((entry_value_len + 1) * FONT_WIDTH_STRIDE),
y,
type_str_buf,
entry_color, rgui->colors.shadow_color);
/* Print entry value */
blit_line(rgui,
fb_width,
ticker_x_offset + term_end_x - ((entry_value_len + 1) * FONT_WIDTH_STRIDE),
y,
type_str_buf,
entry_color, rgui->colors.shadow_color);
break;
case RGUI_ENTRY_VALUE_SWITCH_ON:
rgui_render_toggle_switch(fb_width,
term_end_x - ((entry_value_len + 1) * FONT_WIDTH_STRIDE), y,
true,
entry_color, rgui->colors.shadow_color);
break;
case RGUI_ENTRY_VALUE_SWITCH_OFF:
rgui_render_toggle_switch(fb_width,
term_end_x - ((entry_value_len + 1) * FONT_WIDTH_STRIDE), y,
false,
entry_color, rgui->colors.shadow_color);
break;
case RGUI_ENTRY_VALUE_CHECKMARK:
/* Print marker for currently selected
* item in drop-down lists */
blit_symbol(fb_width, x + FONT_WIDTH_STRIDE, y,
RGUI_SYMBOL_CHECKMARK,
entry_color, rgui->colors.shadow_color);
break;
default:
break;
}
/* Print marker for currently selected item in
* drop down lists, if required */
else if (entry.checked)
blit_symbol(fb_width, x + FONT_WIDTH_STRIDE, y, RGUI_SYMBOL_CHECKMARK,
entry_color, rgui->colors.shadow_color);
/* Print selection marker, if required */
if (entry_selected)

@ -8572,6 +8572,7 @@ unsigned menu_displaylist_build_list(
{MENU_ENUM_LABEL_MENU_TICKER_SMOOTH, PARSE_ONLY_BOOL, true},
{MENU_ENUM_LABEL_OZONE_SCROLL_CONTENT_METADATA, PARSE_ONLY_BOOL, true},
{MENU_ENUM_LABEL_MENU_RGUI_EXTENDED_ASCII, PARSE_ONLY_BOOL, true},
{MENU_ENUM_LABEL_MENU_RGUI_SWITCH_ICONS, PARSE_ONLY_BOOL, true},
};
for (i = 0; i < ARRAY_SIZE(build_list); i++)

@ -13471,6 +13471,21 @@ static bool setting_append_list(
general_write_handler,
general_read_handler,
SD_FLAG_NONE);
CONFIG_BOOL(
list, list_info,
&settings->bools.menu_rgui_switch_icons,
MENU_ENUM_LABEL_MENU_RGUI_SWITCH_ICONS,
MENU_ENUM_LABEL_VALUE_MENU_RGUI_SWITCH_ICONS,
DEFAULT_RGUI_SWITCH_ICONS,
MENU_ENUM_LABEL_VALUE_OFF,
MENU_ENUM_LABEL_VALUE_ON,
&group_info,
&subgroup_info,
parent_group,
general_write_handler,
general_read_handler,
SD_FLAG_NONE);
}
if (string_is_equal(settings->arrays.menu_driver, "xmb"))

@ -1050,6 +1050,7 @@ enum msg_hash_enums
MENU_LABEL(MENU_RGUI_PARTICLE_EFFECT),
MENU_LABEL(MENU_RGUI_PARTICLE_EFFECT_SPEED),
MENU_LABEL(MENU_RGUI_EXTENDED_ASCII),
MENU_LABEL(MENU_RGUI_SWITCH_ICONS),
MENU_LABEL(MENU_LINEAR_FILTER),
MENU_LABEL(MENU_HORIZONTAL_ANIMATION),
MENU_LABEL(NAVIGATION_WRAPAROUND),