mirror of
https://github.com/libretro/RetroArch
synced 2025-03-03 13:14:04 +00:00
Merge pull request #9510 from jdgleaver/dropdown-list-fixes
Menu drop-down lists: Add proper titles, and remember last postion when navigating core options
This commit is contained in:
commit
4428b545bb
@ -135,7 +135,7 @@ void string_remove_all_chars(char *str, char c);
|
||||
|
||||
/* Converts string to unsigned integer.
|
||||
* Returns 0 if string is invalid */
|
||||
unsigned string_to_unsigned(char *str);
|
||||
unsigned string_to_unsigned(const char *str);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
|
@ -321,9 +321,9 @@ void string_remove_all_chars(char *str, char c)
|
||||
|
||||
/* Converts string to unsigned integer.
|
||||
* Returns 0 if string is invalid */
|
||||
unsigned string_to_unsigned(char *str)
|
||||
unsigned string_to_unsigned(const char *str)
|
||||
{
|
||||
char *ptr = NULL;
|
||||
const char *ptr = NULL;
|
||||
|
||||
if (string_is_empty(str))
|
||||
return 0;
|
||||
|
@ -3223,7 +3223,7 @@ int action_ok_core_option_dropdown_list(const char *path,
|
||||
|
||||
generic_action_ok_displaylist_push(
|
||||
core_option_lbl, NULL,
|
||||
core_option_idx, 0, 0, 0,
|
||||
core_option_idx, 0, idx, 0,
|
||||
ACTION_OK_DL_DROPDOWN_BOX_LIST);
|
||||
return 0;
|
||||
}
|
||||
@ -4198,7 +4198,7 @@ static int action_ok_set_core_association(const char *path,
|
||||
return menu_cbs_exit();
|
||||
|
||||
return generic_action_ok_displaylist_push(path, NULL,
|
||||
NULL, 0, menu->rpl_entry_selection_ptr, entry_idx,
|
||||
NULL, 0, idx, entry_idx,
|
||||
ACTION_OK_DL_DEFERRED_CORE_LIST_SET);
|
||||
}
|
||||
|
||||
@ -5701,7 +5701,7 @@ static int action_ok_video_resolution(const char *path,
|
||||
#else
|
||||
generic_action_ok_displaylist_push(
|
||||
NULL,
|
||||
NULL, NULL, 0, 0, 0,
|
||||
NULL, NULL, 0, idx, 0,
|
||||
ACTION_OK_DL_DROPDOWN_BOX_LIST_RESOLUTION);
|
||||
#endif
|
||||
|
||||
@ -5713,7 +5713,7 @@ static int action_ok_playlist_default_core(const char *path,
|
||||
{
|
||||
generic_action_ok_displaylist_push(
|
||||
NULL,
|
||||
NULL, NULL, 0, 0, 0,
|
||||
NULL, NULL, 0, idx, 0,
|
||||
ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_DEFAULT_CORE);
|
||||
return 0;
|
||||
}
|
||||
@ -5723,7 +5723,7 @@ static int action_ok_playlist_label_display_mode(const char *path,
|
||||
{
|
||||
generic_action_ok_displaylist_push(
|
||||
NULL,
|
||||
NULL, NULL, 0, 0, 0,
|
||||
NULL, NULL, 0, idx, 0,
|
||||
ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_LABEL_DISPLAY_MODE);
|
||||
return 0;
|
||||
}
|
||||
@ -5733,7 +5733,7 @@ static int action_ok_playlist_right_thumbnail_mode(const char *path,
|
||||
{
|
||||
generic_action_ok_displaylist_push(
|
||||
NULL,
|
||||
NULL, NULL, 0, 0, 0,
|
||||
NULL, NULL, 0, idx, 0,
|
||||
ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_RIGHT_THUMBNAIL_MODE);
|
||||
return 0;
|
||||
}
|
||||
@ -5743,7 +5743,7 @@ static int action_ok_playlist_left_thumbnail_mode(const char *path,
|
||||
{
|
||||
generic_action_ok_displaylist_push(
|
||||
NULL,
|
||||
NULL, NULL, 0, 0, 0,
|
||||
NULL, NULL, 0, idx, 0,
|
||||
ACTION_OK_DL_DROPDOWN_BOX_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE);
|
||||
return 0;
|
||||
}
|
||||
|
@ -23,6 +23,8 @@
|
||||
#include "../menu_cbs.h"
|
||||
|
||||
#include "../../retroarch.h"
|
||||
#include "../../configuration.h"
|
||||
#include "../managers/core_option_manager.h"
|
||||
|
||||
#ifndef BIND_ACTION_GET_TITLE
|
||||
#define BIND_ACTION_GET_TITLE(cbs, name) \
|
||||
@ -73,8 +75,165 @@ static int action_get_title_action_generic(const char *path, const char *label,
|
||||
return 1; \
|
||||
}
|
||||
|
||||
static int action_get_title_thumbnails(
|
||||
const char *path, const char *label, unsigned menu_type, char *s, size_t len)
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
const char *title = NULL;
|
||||
enum msg_hash_enums label_value;
|
||||
|
||||
/* Get label value */
|
||||
if (string_is_equal(settings->arrays.menu_driver, "rgui"))
|
||||
label_value = MENU_ENUM_LABEL_VALUE_THUMBNAILS_RGUI;
|
||||
else
|
||||
label_value = MENU_ENUM_LABEL_VALUE_THUMBNAILS;
|
||||
|
||||
title = msg_hash_to_str(label_value);
|
||||
|
||||
if (s && !string_is_empty(title))
|
||||
{
|
||||
sanitize_to_string(s, title, len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int action_get_title_left_thumbnails(
|
||||
const char *path, const char *label, unsigned menu_type, char *s, size_t len)
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
const char *title = NULL;
|
||||
enum msg_hash_enums label_value;
|
||||
|
||||
/* Get label value */
|
||||
if (string_is_equal(settings->arrays.menu_driver, "rgui"))
|
||||
label_value = MENU_ENUM_LABEL_VALUE_LEFT_THUMBNAILS_RGUI;
|
||||
else if (string_is_equal(settings->arrays.menu_driver, "ozone"))
|
||||
label_value = MENU_ENUM_LABEL_VALUE_LEFT_THUMBNAILS_OZONE;
|
||||
else
|
||||
label_value = MENU_ENUM_LABEL_VALUE_LEFT_THUMBNAILS;
|
||||
|
||||
title = msg_hash_to_str(label_value);
|
||||
|
||||
if (s && !string_is_empty(title))
|
||||
{
|
||||
sanitize_to_string(s, title, len);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int action_get_title_dropdown_item(const char *path, const char *label, unsigned menu_type, char *s, size_t len)
|
||||
{
|
||||
/* Sanity check */
|
||||
if (string_is_empty(path))
|
||||
return 0;
|
||||
|
||||
if (strstr(path, "core_option_"))
|
||||
{
|
||||
/* This is a core options item */
|
||||
struct string_list *tmp_str_list = string_split(path, "_");
|
||||
int ret = 0;
|
||||
|
||||
if (tmp_str_list && tmp_str_list->size > 0)
|
||||
{
|
||||
core_option_manager_t *coreopts = NULL;
|
||||
|
||||
rarch_ctl(RARCH_CTL_CORE_OPTIONS_LIST_GET, &coreopts);
|
||||
|
||||
if (coreopts)
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
unsigned menu_index = string_to_unsigned(tmp_str_list->elems[(unsigned)tmp_str_list->size - 1].data);
|
||||
unsigned visible_index = 0;
|
||||
unsigned option_index = 0;
|
||||
bool option_found = false;
|
||||
struct core_option *option = NULL;
|
||||
unsigned i;
|
||||
|
||||
/* Convert menu index to option index */
|
||||
if (settings->bools.game_specific_options)
|
||||
menu_index--;
|
||||
|
||||
for (i = 0; i < coreopts->size; i++)
|
||||
{
|
||||
if (core_option_manager_get_visible(coreopts, i))
|
||||
{
|
||||
if (visible_index == menu_index)
|
||||
{
|
||||
option_found = true;
|
||||
option_index = i;
|
||||
break;
|
||||
}
|
||||
visible_index++;
|
||||
}
|
||||
}
|
||||
|
||||
/* If option was found, title == option description */
|
||||
if (option_found)
|
||||
{
|
||||
const char *title = core_option_manager_get_desc(coreopts, option_index);
|
||||
|
||||
if (s && !string_is_empty(title))
|
||||
{
|
||||
sanitize_to_string(s, title, len);
|
||||
ret = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Clean up */
|
||||
if (tmp_str_list)
|
||||
string_list_free(tmp_str_list);
|
||||
|
||||
return ret;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* This is a 'normal' drop down list */
|
||||
|
||||
/* In msg_hash.h, msg_hash_enums are generated via
|
||||
* the following macro:
|
||||
* #define MENU_LABEL(STR) \
|
||||
* MENU_ENUM_LABEL_##STR, \
|
||||
* MENU_ENUM_SUBLABEL_##STR, \
|
||||
* MENU_ENUM_LABEL_VALUE_##STR
|
||||
* to get 'MENU_ENUM_LABEL_VALUE_' from a
|
||||
* 'MENU_ENUM_LABEL_', we therefore add 2... */
|
||||
enum msg_hash_enums enum_idx = (enum msg_hash_enums)(string_to_unsigned(path) + 2);
|
||||
|
||||
/* Check if enum index is valid
|
||||
* Note: This is a very crude check, but better than nothing */
|
||||
if ((enum_idx > MSG_UNKNOWN) && (enum_idx < MSG_LAST))
|
||||
{
|
||||
/* An annoyance: MENU_ENUM_LABEL_THUMBNAILS and
|
||||
* MENU_ENUM_LABEL_LEFT_THUMBNAILS require special
|
||||
* treatment, since their titles depend upon the
|
||||
* current menu driver... */
|
||||
if (enum_idx == MENU_ENUM_LABEL_VALUE_THUMBNAILS)
|
||||
{
|
||||
return action_get_title_thumbnails(path, label, menu_type, s, len);
|
||||
}
|
||||
else if (enum_idx == MENU_ENUM_LABEL_VALUE_LEFT_THUMBNAILS)
|
||||
{
|
||||
return action_get_title_left_thumbnails(path, label, menu_type, s, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
const char *title = msg_hash_to_str(enum_idx);
|
||||
|
||||
if (s && !string_is_empty(title))
|
||||
{
|
||||
sanitize_to_string(s, title, len);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -130,6 +289,18 @@ static int action_get_title_deferred_playlist_list(const char *path, const char
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int action_get_title_dropdown_playlist_right_thumbnail_mode_item(
|
||||
const char *path, const char *label, unsigned menu_type, char *s, size_t len)
|
||||
{
|
||||
return action_get_title_thumbnails(path, label, menu_type, s, len);
|
||||
}
|
||||
|
||||
static int action_get_title_dropdown_playlist_left_thumbnail_mode_item(
|
||||
const char *path, const char *label, unsigned menu_type, char *s, size_t len)
|
||||
{
|
||||
return action_get_title_left_thumbnails(path, label, menu_type, s, len);
|
||||
}
|
||||
|
||||
default_title_macro(action_get_quick_menu_override_options, MENU_ENUM_LABEL_VALUE_QUICK_MENU_OVERRIDE_OPTIONS)
|
||||
default_title_macro(action_get_user_accounts_cheevos_list, MENU_ENUM_LABEL_VALUE_ACCOUNTS_RETRO_ACHIEVEMENTS)
|
||||
default_title_macro(action_get_user_accounts_youtube_list, MENU_ENUM_LABEL_VALUE_ACCOUNTS_YOUTUBE)
|
||||
@ -221,6 +392,10 @@ default_title_macro(action_get_title_goto_video, MENU_ENUM_LABEL_
|
||||
default_title_macro(action_get_title_collection, MENU_ENUM_LABEL_VALUE_PLAYLISTS_TAB)
|
||||
default_title_macro(action_get_title_deferred_core_list, MENU_ENUM_LABEL_VALUE_SUPPORTED_CORES)
|
||||
|
||||
default_title_macro(action_get_title_dropdown_resolution_item, MENU_ENUM_LABEL_VALUE_SCREEN_RESOLUTION)
|
||||
default_title_macro(action_get_title_dropdown_playlist_default_core_item, MENU_ENUM_LABEL_VALUE_PLAYLIST_MANAGER_DEFAULT_CORE)
|
||||
default_title_macro(action_get_title_dropdown_playlist_label_display_mode_item, MENU_ENUM_LABEL_VALUE_PLAYLIST_MANAGER_LABEL_DISPLAY_MODE)
|
||||
|
||||
default_fill_title_macro(action_get_title_disk_image_append, MENU_ENUM_LABEL_VALUE_DISK_IMAGE_APPEND)
|
||||
default_fill_title_macro(action_get_title_cheat_file_load, MENU_ENUM_LABEL_VALUE_CHEAT_FILE)
|
||||
default_fill_title_macro(action_get_title_cheat_file_load_append, MENU_ENUM_LABEL_VALUE_CHEAT_FILE_APPEND)
|
||||
@ -1426,44 +1601,44 @@ int menu_cbs_init_bind_title(menu_file_list_cbs_t *cbs,
|
||||
if (string_is_equal(label,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST)))
|
||||
{
|
||||
BIND_ACTION_GET_TITLE(cbs, action_get_title_dropdown_item);
|
||||
return 0;
|
||||
BIND_ACTION_GET_TITLE(cbs, action_get_title_dropdown_item);
|
||||
return 0;
|
||||
}
|
||||
if (string_is_equal(label,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_SPECIAL)))
|
||||
{
|
||||
BIND_ACTION_GET_TITLE(cbs, action_get_title_dropdown_item);
|
||||
return 0;
|
||||
BIND_ACTION_GET_TITLE(cbs, action_get_title_dropdown_item);
|
||||
return 0;
|
||||
}
|
||||
if (string_is_equal(label,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_RESOLUTION)))
|
||||
{
|
||||
BIND_ACTION_GET_TITLE(cbs, action_get_title_dropdown_item);
|
||||
return 0;
|
||||
BIND_ACTION_GET_TITLE(cbs, action_get_title_dropdown_resolution_item);
|
||||
return 0;
|
||||
}
|
||||
if (string_is_equal(label,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_DEFAULT_CORE)))
|
||||
{
|
||||
BIND_ACTION_GET_TITLE(cbs, action_get_title_dropdown_item);
|
||||
return 0;
|
||||
BIND_ACTION_GET_TITLE(cbs, action_get_title_dropdown_playlist_default_core_item);
|
||||
return 0;
|
||||
}
|
||||
if (string_is_equal(label,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_LABEL_DISPLAY_MODE)))
|
||||
{
|
||||
BIND_ACTION_GET_TITLE(cbs, action_get_title_dropdown_item);
|
||||
return 0;
|
||||
BIND_ACTION_GET_TITLE(cbs, action_get_title_dropdown_playlist_label_display_mode_item);
|
||||
return 0;
|
||||
}
|
||||
if (string_is_equal(label,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_RIGHT_THUMBNAIL_MODE)))
|
||||
{
|
||||
BIND_ACTION_GET_TITLE(cbs, action_get_title_dropdown_item);
|
||||
return 0;
|
||||
BIND_ACTION_GET_TITLE(cbs, action_get_title_dropdown_playlist_right_thumbnail_mode_item);
|
||||
return 0;
|
||||
}
|
||||
if (string_is_equal(label,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_PLAYLIST_LEFT_THUMBNAIL_MODE)))
|
||||
{
|
||||
BIND_ACTION_GET_TITLE(cbs, action_get_title_dropdown_item);
|
||||
return 0;
|
||||
BIND_ACTION_GET_TITLE(cbs, action_get_title_dropdown_playlist_left_thumbnail_mode_item);
|
||||
return 0;
|
||||
}
|
||||
if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_RPL_ENTRY_ACTIONS)))
|
||||
{
|
||||
|
@ -6922,11 +6922,15 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type,
|
||||
* toggles the Quick Menu off and on again (returning
|
||||
* to the Core Options menu) the menu must be refreshed
|
||||
* (or undefined behaviour occurs).
|
||||
* The only way to check whether the number of visible
|
||||
* options has changed is to cache the last set menu size,
|
||||
* We therefore have to cache the last set menu size,
|
||||
* and compare this with the new size after processing
|
||||
* the current core_option_manager_t struct */
|
||||
size_t prev_count = info->list->size;
|
||||
* the current core_option_manager_t struct.
|
||||
* Note: It would be 'nicer' to only refresh the menu
|
||||
* if the selection marker is at an index higher than
|
||||
* the new size, but we don't really have access that
|
||||
* information at this stage (i.e. the selection can
|
||||
* change after this function is called) */
|
||||
static size_t prev_count = 0;
|
||||
|
||||
menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list);
|
||||
|
||||
@ -6992,6 +6996,7 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type,
|
||||
{
|
||||
info->need_refresh = true;
|
||||
info->need_navigation_clear = true;
|
||||
prev_count = count;
|
||||
}
|
||||
info->need_push = true;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user