diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index 090ca96d20..82a15774ce 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -257,6 +257,8 @@ MSG_HASH(MENU_ENUM_LABEL_DATABASE_MANAGER_LIST, "database_manager_list") MSG_HASH(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST, "deferred_dropdown_box_list") +MSG_HASH(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_SPECIAL, + "deferred_dropdown_box_list_special") MSG_HASH(MENU_ENUM_LABEL_DEFERRED_CONFIGURATIONS_LIST, "deferred_configurations_list") MSG_HASH(MENU_ENUM_LABEL_DEFERRED_PLAYLIST_LIST, diff --git a/menu/cbs/menu_cbs_deferred_push.c b/menu/cbs/menu_cbs_deferred_push.c index 6d9e29574d..39fd92b9ff 100644 --- a/menu/cbs/menu_cbs_deferred_push.c +++ b/menu/cbs/menu_cbs_deferred_push.c @@ -612,6 +612,7 @@ generic_deferred_push_clear_general(deferred_music_history_list, PUSH_DEFAULT, D generic_deferred_push_clear_general(deferred_image_history_list, PUSH_DEFAULT, DISPLAYLIST_IMAGES_HISTORY) generic_deferred_push_clear_general(deferred_video_history_list, PUSH_DEFAULT, DISPLAYLIST_VIDEO_HISTORY) generic_deferred_push_clear_general(deferred_push_dropdown_box_list, PUSH_DEFAULT, DISPLAYLIST_DROPDOWN_LIST) +generic_deferred_push_clear_general(deferred_push_dropdown_box_list_special, PUSH_DEFAULT, DISPLAYLIST_DROPDOWN_LIST_SPECIAL) static int menu_cbs_init_bind_deferred_push_compare_label( menu_file_list_cbs_t *cbs, @@ -627,6 +628,11 @@ static int menu_cbs_init_bind_deferred_push_compare_label( BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_dropdown_box_list); return 0; } + else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_SPECIAL))) + { + BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_dropdown_box_list_special); + return 0; + } else if (string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_BROWSE_URL_LIST))) { BIND_ACTION_DEFERRED_PUSH(cbs, deferred_push_browse_url_list); diff --git a/menu/cbs/menu_cbs_ok.c b/menu/cbs/menu_cbs_ok.c index fc9df18401..577e7d993e 100644 --- a/menu/cbs/menu_cbs_ok.c +++ b/menu/cbs/menu_cbs_ok.c @@ -148,6 +148,8 @@ static enum msg_hash_enums action_ok_dl_to_enum(unsigned lbl) { case ACTION_OK_DL_DROPDOWN_BOX_LIST: return MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST; + case ACTION_OK_DL_DROPDOWN_BOX_LIST_SPECIAL: + return MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_SPECIAL; case ACTION_OK_DL_MIXER_STREAM_SETTINGS_LIST: return MENU_ENUM_LABEL_DEFERRED_MIXER_STREAM_SETTINGS_LIST; case ACTION_OK_DL_ACCOUNTS_LIST: @@ -312,6 +314,15 @@ int generic_action_ok_displaylist_push(const char *path, info.enum_idx = MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST; dl_type = DISPLAYLIST_GENERIC; break; + case ACTION_OK_DL_DROPDOWN_BOX_LIST_SPECIAL: + info.type = type; + info.directory_ptr = idx; + info_path = path; + info_label = msg_hash_to_str( + MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_SPECIAL); + info.enum_idx = MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_SPECIAL; + dl_type = DISPLAYLIST_GENERIC; + break; case ACTION_OK_DL_USER_BINDS_LIST: info.type = type; info.directory_ptr = idx; @@ -4260,6 +4271,89 @@ int action_ok_push_filebrowser_list_file_select(const char *path, entry_idx, ACTION_OK_DL_FILE_BROWSER_SELECT_DIR); } +/* TODO/FIXME */ +static int action_ok_push_dropdown_setting_core_options_item_special(const char *path, + const char *label, unsigned type, size_t idx, size_t entry_idx) +{ + core_option_manager_t *coreopts = NULL; + int core_option_idx = (int)atoi(label); + + rarch_ctl(RARCH_CTL_CORE_OPTIONS_LIST_GET, &coreopts); + + if (!coreopts) + return -1; + + core_option_manager_set_val(coreopts, core_option_idx, idx); + return action_cancel_pop_default(NULL, NULL, 0, 0); +} + +/* TODO/FIXME */ +static int action_ok_push_dropdown_setting_string_options_item_special(const char *path, + const char *label, unsigned type, size_t idx, size_t entry_idx) +{ + enum msg_hash_enums enum_idx = (enum msg_hash_enums)atoi(label); + rarch_setting_t *setting = menu_setting_find_enum(enum_idx); + + if (!setting) + return -1; + + strlcpy(setting->value.target.string, path, + setting->size); + return action_cancel_pop_default(NULL, NULL, 0, 0); +} + +/* TODO/FIXME */ +static int action_ok_push_dropdown_setting_int_item_special(const char *path, + const char *label, unsigned type, size_t idx, size_t entry_idx) +{ + enum msg_hash_enums enum_idx = (enum msg_hash_enums)atoi(label); + rarch_setting_t *setting = menu_setting_find_enum(enum_idx); + + if (!setting) + return -1; + + *setting->value.target.integer = (int32_t)(idx + setting->offset_by); + return action_cancel_pop_default(NULL, NULL, 0, 0); +} + +/* TODO/FIXME */ +static int action_ok_push_dropdown_setting_float_item_special(const char *path, + const char *label, unsigned type, size_t idx, size_t entry_idx) +{ + enum msg_hash_enums enum_idx = (enum msg_hash_enums)atoi(label); + rarch_setting_t *setting = menu_setting_find_enum(enum_idx); + float val = (float)atof(path); + + if (!setting) + return -1; + + *setting->value.target.fraction = (float)val; + return action_cancel_pop_default(NULL, NULL, 0, 0); +} + +static int action_ok_push_dropdown_setting_uint_item_special(const char *path, + const char *label, unsigned type, size_t idx, size_t entry_idx) +{ + unsigned value; + enum msg_hash_enums enum_idx = (enum msg_hash_enums)atoi(label); + rarch_setting_t *setting = menu_setting_find_enum(enum_idx); + + if (!setting) + return -1; + + value = (unsigned)(idx + setting->offset_by); + + if (!string_is_empty(path)) + { + unsigned path_value = atoi(path); + if (path_value != value) + value = path_value; + } + + *setting->value.target.unsigned_integer = value; + return action_cancel_pop_default(NULL, NULL, 0, 0); +} + static int action_ok_push_dropdown_setting_core_options_item(const char *path, const char *label, unsigned type, size_t idx, size_t entry_idx) { @@ -5443,6 +5537,21 @@ static int menu_cbs_init_bind_ok_compare_type(menu_file_list_cbs_t *cbs, case MENU_SETTING_DROPDOWN_SETTING_UINT_ITEM: BIND_ACTION_OK(cbs, action_ok_push_dropdown_setting_uint_item); break; + case MENU_SETTING_DROPDOWN_SETTING_CORE_OPTIONS_ITEM_SPECIAL: + BIND_ACTION_OK(cbs, action_ok_push_dropdown_setting_core_options_item_special); + break; + case MENU_SETTING_DROPDOWN_SETTING_STRING_OPTIONS_ITEM_SPECIAL: + BIND_ACTION_OK(cbs, action_ok_push_dropdown_setting_string_options_item_special); + break; + case MENU_SETTING_DROPDOWN_SETTING_INT_ITEM_SPECIAL: + BIND_ACTION_OK(cbs, action_ok_push_dropdown_setting_int_item_special); + break; + case MENU_SETTING_DROPDOWN_SETTING_FLOAT_ITEM_SPECIAL: + BIND_ACTION_OK(cbs, action_ok_push_dropdown_setting_float_item_special); + break; + case MENU_SETTING_DROPDOWN_SETTING_UINT_ITEM_SPECIAL: + BIND_ACTION_OK(cbs, action_ok_push_dropdown_setting_uint_item_special); + break; case MENU_SETTING_DROPDOWN_ITEM: BIND_ACTION_OK(cbs, action_ok_push_dropdown_item); break; diff --git a/menu/menu_cbs.h b/menu/menu_cbs.h index 76482efcb9..1b69dffcd7 100644 --- a/menu/menu_cbs.h +++ b/menu/menu_cbs.h @@ -44,6 +44,7 @@ enum { ACTION_OK_DL_DEFAULT = 0, ACTION_OK_DL_DROPDOWN_BOX_LIST, + ACTION_OK_DL_DROPDOWN_BOX_LIST_SPECIAL, ACTION_OK_DL_OPEN_ARCHIVE, ACTION_OK_DL_OPEN_ARCHIVE_DETECT_CORE, ACTION_OK_DL_MUSIC, diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index 5c27a39e75..2016a0db27 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -8302,6 +8302,315 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist info->need_push = true; } break; + case DISPLAYLIST_DROPDOWN_LIST_SPECIAL: + { + menu_entries_ctl(MENU_ENTRIES_CTL_CLEAR, info->list); + + if (strstr(info->path, "core_option_")) + { + struct string_list *tmp_str_list = string_split(info->path, "_"); + + 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) + { + unsigned size = (unsigned)tmp_str_list->size; + unsigned i = atoi(tmp_str_list->elems[size-1].data); + struct core_option *option = NULL; + bool checked_found = false; + unsigned checked = 0; + const char *val = core_option_manager_get_val(coreopts, i-1); + + i--; + + option = (struct core_option*)&coreopts->opts[i]; + + if (option) + { + unsigned k; + for (k = 0; k < option->vals->size; k++) + { + const char *str = option->vals->elems[k].data; + + if (!string_is_empty(str)) + { + char val_d[256]; + snprintf(val_d, sizeof(val_d), "%d", i); + menu_entries_append_enum(info->list, + str, + val_d, + MENU_ENUM_LABEL_NO_ITEMS, + MENU_SETTING_DROPDOWN_SETTING_CORE_OPTIONS_ITEM_SPECIAL, k, 0); + + if (!checked_found && string_is_equal(str, val)) + { + checked = k; + checked_found = true; + } + + count++; + } + } + + if (checked_found) + menu_entries_set_checked(info->list, checked, true); + } + } + } + + } + else + { + enum msg_hash_enums enum_idx = (enum msg_hash_enums)atoi(info->path); + rarch_setting_t *setting = menu_setting_find_enum(enum_idx); + + if (setting) + { + switch (setting->type) + { + case ST_STRING_OPTIONS: + { + struct string_list *tmp_str_list = string_split(setting->values, "|"); + + if (tmp_str_list && tmp_str_list->size > 0) + { + unsigned i; + unsigned size = (unsigned)tmp_str_list->size; + bool checked_found = false; + unsigned checked = 0; + + for (i = 0; i < size; i++) + { + char val_d[256]; + snprintf(val_d, sizeof(val_d), "%d", setting->enum_idx); + menu_entries_append_enum(info->list, + tmp_str_list->elems[i].data, + val_d, + MENU_ENUM_LABEL_NO_ITEMS, + MENU_SETTING_DROPDOWN_SETTING_STRING_OPTIONS_ITEM_SPECIAL, i, 0); + + if (!checked_found && string_is_equal(tmp_str_list->elems[i].data, setting->value.target.string)) + { + checked = i; + checked_found = true; + } + } + + if (checked_found) + menu_entries_set_checked(info->list, checked, true); + } + } + break; + case ST_INT: + { + float i; + int32_t orig_value = *setting->value.target.integer; + unsigned setting_type = MENU_SETTING_DROPDOWN_SETTING_INT_ITEM_SPECIAL; + float step = setting->step; + double min = setting->enforce_minrange ? setting->min : 0.00; + double max = setting->enforce_maxrange ? setting->max : 999.00; + bool checked_found = false; + unsigned checked = 0; + + if (setting->get_string_representation) + { + for (i = min; i <= max; i += step) + { + char val_s[256], val_d[256]; + int val = (int)i; + + *setting->value.target.integer = val; + + setting->get_string_representation(setting, + val_s, sizeof(val_s)); + snprintf(val_d, sizeof(val_d), "%d", setting->enum_idx); + menu_entries_append_enum(info->list, + val_s, + val_d, + MENU_ENUM_LABEL_NO_ITEMS, + setting_type, val, 0); + + if (!checked_found && string_is_equal(val_s, setting->value.target.string)) + { + checked = i; + checked_found = true; + } + } + + *setting->value.target.integer = orig_value; + } + else + { + for (i = min; i <= max; i += step) + { + char val_s[16], val_d[16]; + int val = (int)i; + + snprintf(val_s, sizeof(val_s), "%d", val); + snprintf(val_d, sizeof(val_d), "%d", setting->enum_idx); + + menu_entries_append_enum(info->list, + val_s, + val_d, + MENU_ENUM_LABEL_NO_ITEMS, + setting_type, val, 0); + + if (!checked_found && string_is_equal(val_s, setting->value.target.string)) + { + checked = i; + checked_found = true; + } + } + } + + if (checked_found) + menu_entries_set_checked(info->list, checked, true); + } + break; + case ST_FLOAT: + { + float i; + float orig_value = *setting->value.target.fraction; + unsigned setting_type = MENU_SETTING_DROPDOWN_SETTING_FLOAT_ITEM_SPECIAL; + float step = setting->step; + double min = setting->enforce_minrange ? setting->min : 0.00; + double max = setting->enforce_maxrange ? setting->max : 999.00; + bool checked_found = false; + unsigned checked = 0; + + if (setting->get_string_representation) + { + for (i = min; i <= max; i += step) + { + char val_s[256], val_d[256]; + + *setting->value.target.fraction = i; + + setting->get_string_representation(setting, + val_s, sizeof(val_s)); + snprintf(val_d, sizeof(val_d), "%d", setting->enum_idx); + menu_entries_append_enum(info->list, + val_s, + val_d, + MENU_ENUM_LABEL_NO_ITEMS, + setting_type, 0, 0); + + if (!checked_found && string_is_equal(val_s, setting->value.target.string)) + { + checked = i; + checked_found = true; + } + } + + *setting->value.target.fraction = orig_value; + } + else + { + for (i = min; i <= max; i += step) + { + char val_s[16], val_d[16]; + + snprintf(val_s, sizeof(val_s), "%.2f", i); + snprintf(val_d, sizeof(val_d), "%d", setting->enum_idx); + + menu_entries_append_enum(info->list, + val_s, + val_d, + MENU_ENUM_LABEL_NO_ITEMS, + setting_type, 0, 0); + + if (!checked_found && string_is_equal(val_s, setting->value.target.string)) + { + checked = i; + checked_found = true; + } + } + } + + if (checked_found) + menu_entries_set_checked(info->list, checked, true); + } + break; + case ST_UINT: + { + float i; + unsigned orig_value = *setting->value.target.unsigned_integer; + unsigned setting_type = MENU_SETTING_DROPDOWN_SETTING_UINT_ITEM_SPECIAL; + float step = setting->step; + double min = setting->enforce_minrange ? setting->min : 0.00; + double max = setting->enforce_maxrange ? setting->max : 999.00; + bool checked_found = false; + unsigned checked = 0; + + if (setting->get_string_representation) + { + for (i = min; i <= max; i += step) + { + char val_s[256], val_d[256]; + int val = (int)i; + + *setting->value.target.unsigned_integer = val; + + setting->get_string_representation(setting, + val_s, sizeof(val_s)); + snprintf(val_d, sizeof(val_d), "%d", setting->enum_idx); + menu_entries_append_enum(info->list, + val_s, + val_d, + MENU_ENUM_LABEL_NO_ITEMS, + setting_type, val, 0); + + if (!checked_found && string_is_equal(val_s, setting->value.target.string)) + { + checked = i; + checked_found = true; + } + } + + *setting->value.target.unsigned_integer = orig_value; + } + else + { + for (i = min; i <= max; i += step) + { + char val_s[16], val_d[16]; + int val = (int)i; + + snprintf(val_s, sizeof(val_s), "%d", val); + snprintf(val_d, sizeof(val_d), "%d", setting->enum_idx); + + menu_entries_append_enum(info->list, + val_s, + val_d, + MENU_ENUM_LABEL_NO_ITEMS, + setting_type, val, 0); + + if (!checked_found && string_is_equal(val_s, setting->value.target.string)) + { + checked = i; + checked_found = true; + } + } + } + + if (checked_found) + menu_entries_set_checked(info->list, checked, true); + } + break; + default: + break; + } + } + } + + info->need_refresh = true; + info->need_push = true; + } + break; case DISPLAYLIST_NONE: break; } diff --git a/menu/menu_displaylist.h b/menu/menu_displaylist.h index e5e4b948cd..79b8603dbd 100644 --- a/menu/menu_displaylist.h +++ b/menu/menu_displaylist.h @@ -55,6 +55,7 @@ enum menu_displaylist_ctl_state { DISPLAYLIST_NONE = 0, DISPLAYLIST_DROPDOWN_LIST, + DISPLAYLIST_DROPDOWN_LIST_SPECIAL, DISPLAYLIST_INFO, DISPLAYLIST_HELP, DISPLAYLIST_HELP_SCREEN_LIST, diff --git a/menu/menu_driver.h b/menu/menu_driver.h index 917265740f..48d9e02c44 100644 --- a/menu/menu_driver.h +++ b/menu/menu_driver.h @@ -146,6 +146,11 @@ enum menu_settings_type MENU_SETTING_DROPDOWN_SETTING_FLOAT_ITEM, MENU_SETTING_DROPDOWN_SETTING_INT_ITEM, MENU_SETTING_DROPDOWN_SETTING_UINT_ITEM, + MENU_SETTING_DROPDOWN_SETTING_CORE_OPTIONS_ITEM_SPECIAL, + MENU_SETTING_DROPDOWN_SETTING_STRING_OPTIONS_ITEM_SPECIAL, + MENU_SETTING_DROPDOWN_SETTING_FLOAT_ITEM_SPECIAL, + MENU_SETTING_DROPDOWN_SETTING_INT_ITEM_SPECIAL, + MENU_SETTING_DROPDOWN_SETTING_UINT_ITEM_SPECIAL, MENU_SETTING_NO_ITEM, MENU_SETTING_DRIVER, MENU_SETTING_ACTION, diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 8e76404a34..dc93e5d2c7 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -271,6 +271,20 @@ static int setting_action_ok_video_refresh_rate_polled(rarch_setting_t *setting, return 0; } +static int setting_action_ok_uint_special(rarch_setting_t *setting, bool wraparound) +{ + char enum_idx[16]; + if (!setting) + return -1; + + snprintf(enum_idx, sizeof(enum_idx), "%d", setting->enum_idx); + + generic_action_ok_displaylist_push( + enum_idx, /* we will pass the enumeration index of the string as a path */ + NULL, NULL, 0, 0, 0, + ACTION_OK_DL_DROPDOWN_BOX_LIST_SPECIAL); + return 0; +} static int setting_action_ok_uint(rarch_setting_t *setting, bool wraparound) { @@ -6168,7 +6182,7 @@ static bool setting_append_list( parent_group, general_write_handler, general_read_handler); - (*list)[list_info->index - 1].action_ok = &setting_action_ok_uint; + (*list)[list_info->index - 1].action_ok = &setting_action_ok_uint_special; menu_settings_list_current_add_range(list, list_info, 1000, 192000, 100.0, true, true); settings_data_list_current_add_flags(list, list_info, SD_FLAG_ADVANCED); diff --git a/msg_hash.h b/msg_hash.h index 06bbec81f4..d5255e0979 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -1011,6 +1011,7 @@ enum msg_hash_enums MENU_LABEL(BROWSE_START), /* Deferred */ MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST, + MENU_ENUM_LABEL_DEFERRED_DROPDOWN_BOX_LIST_SPECIAL, MENU_ENUM_LABEL_DEFERRED_MIXER_STREAM_SETTINGS_LIST, MENU_ENUM_LABEL_DEFERRED_CONFIGURATIONS_LIST, MENU_ENUM_LABEL_DEFERRED_FAVORITES_LIST,