mirror of
https://github.com/libretro/RetroArch
synced 2025-01-31 06:32:48 +00:00
(menu_explore.c) Cleanups
This commit is contained in:
parent
c7a3581ee5
commit
3517091a1e
@ -1160,13 +1160,13 @@ static int explore_action_ok_saveview(const char *path, const char *label, unsig
|
||||
|
||||
static void explore_load_view(explore_state_t *state, const char* path)
|
||||
{
|
||||
unsigned cat;
|
||||
rjson_t *json;
|
||||
intfstream_t *file;
|
||||
rjson_t* json;
|
||||
uint8_t op = ((uint8_t)-1);
|
||||
unsigned cat;
|
||||
enum rjson_type type;
|
||||
uint8_t op = ((uint8_t)-1);
|
||||
|
||||
state->view_levels = 0;
|
||||
state->view_levels = 0;
|
||||
state->view_search[0] = '\0';
|
||||
|
||||
if (!(file = intfstream_open_file(path,
|
||||
@ -1185,19 +1185,18 @@ static void explore_load_view(explore_state_t *state, const char* path)
|
||||
if (depth == 1 && type == RJSON_STRING)
|
||||
{
|
||||
const char* key = rjson_get_string(json, NULL);
|
||||
if (string_is_equal(key, "filter_name")
|
||||
&& rjson_next(json) == RJSON_STRING)
|
||||
if (string_is_equal(key, "filter_name") &&
|
||||
rjson_next(json) == RJSON_STRING)
|
||||
strlcpy(state->view_search,
|
||||
rjson_get_string(json, NULL),
|
||||
sizeof(state->view_search));
|
||||
else if (string_is_equal(key, "filter_equal")
|
||||
&& rjson_next(json) == RJSON_OBJECT)
|
||||
rjson_get_string(json, NULL), sizeof(state->view_search));
|
||||
else if (string_is_equal(key, "filter_equal") &&
|
||||
rjson_next(json) == RJSON_OBJECT)
|
||||
op = EXPLORE_OP_EQUAL;
|
||||
else if (string_is_equal(key, "filter_min")
|
||||
&& rjson_next(json) == RJSON_OBJECT)
|
||||
else if (string_is_equal(key, "filter_min") &&
|
||||
rjson_next(json) == RJSON_OBJECT)
|
||||
op = EXPLORE_OP_MIN;
|
||||
else if (string_is_equal(key, "filter_max")
|
||||
&& rjson_next(json) == RJSON_OBJECT)
|
||||
else if (string_is_equal(key, "filter_max") &&
|
||||
rjson_next(json) == RJSON_OBJECT)
|
||||
op = EXPLORE_OP_MAX;
|
||||
}
|
||||
else if (depth == 2 && type == RJSON_STRING && op != ((uint8_t)-1))
|
||||
@ -1211,11 +1210,11 @@ static void explore_load_view(explore_state_t *state, const char* path)
|
||||
else
|
||||
{
|
||||
explore_string_t **entries = state->by[cat];
|
||||
const char *value = NULL;
|
||||
unsigned lvl, lvl_max = state->view_levels;
|
||||
uint8_t valid_op = ((uint8_t)-1);
|
||||
const char* value = NULL;
|
||||
unsigned lvl, lvl_max = state->view_levels;
|
||||
uint8_t valid_op = ((uint8_t)-1);
|
||||
|
||||
type = rjson_next(json);
|
||||
type = rjson_next(json);
|
||||
if (type == RJSON_STRING || type == RJSON_NUMBER)
|
||||
value = rjson_get_string(json, NULL);
|
||||
if (value && !*value)
|
||||
@ -1228,15 +1227,15 @@ static void explore_load_view(explore_state_t *state, const char* path)
|
||||
if (!value && state->has_unknown[cat] && op == EXPLORE_OP_EQUAL)
|
||||
{
|
||||
state->view_match[lvl] = NULL;
|
||||
valid_op = EXPLORE_OP_EQUAL;
|
||||
valid_op = EXPLORE_OP_EQUAL;
|
||||
}
|
||||
else if (value && entries)
|
||||
{
|
||||
int cmp;
|
||||
/* Use existing qsort function for binary search */
|
||||
/* use existing qsort function for binary search */
|
||||
explore_string_t *evalue = (explore_string_t *)
|
||||
(value - offsetof(explore_string_t, str));
|
||||
uint32_t i, ifrom, ito, imax = (uint32_t)RBUF_LEN(entries);
|
||||
int cmp;
|
||||
int (*compare_func)(const void *, const void *) =
|
||||
(explore_by_info[cat].is_numeric
|
||||
? explore_qsort_func_nums
|
||||
@ -1256,21 +1255,19 @@ static void explore_load_view(explore_state_t *state, const char* path)
|
||||
if (op == EXPLORE_OP_EQUAL && !cmp)
|
||||
{
|
||||
state->view_match[lvl] = entries[i];
|
||||
valid_op = EXPLORE_OP_EQUAL;
|
||||
valid_op = EXPLORE_OP_EQUAL;
|
||||
}
|
||||
else if (op == EXPLORE_OP_MIN)
|
||||
{
|
||||
state->view_idx_min[lvl] = (cmp ? i + 1 : i);
|
||||
valid_op = ((lvl != lvl_max && state->view_op[lvl] == EXPLORE_OP_MAX)
|
||||
? EXPLORE_OP_RANGE
|
||||
: EXPLORE_OP_MIN);
|
||||
valid_op = ((lvl != lvl_max && state->view_op[lvl] == EXPLORE_OP_MAX)
|
||||
? EXPLORE_OP_RANGE : EXPLORE_OP_MIN);
|
||||
}
|
||||
else if (op == EXPLORE_OP_MAX)
|
||||
{
|
||||
state->view_idx_max[lvl] = i;
|
||||
valid_op = ((lvl != lvl_max && state->view_op[lvl] == EXPLORE_OP_MIN)
|
||||
? EXPLORE_OP_RANGE
|
||||
: EXPLORE_OP_MAX);
|
||||
valid_op = ((lvl != lvl_max && state->view_op[lvl] == EXPLORE_OP_MIN)
|
||||
? EXPLORE_OP_RANGE : EXPLORE_OP_MAX);
|
||||
}
|
||||
}
|
||||
if (valid_op != ((uint8_t)-1))
|
||||
@ -1278,13 +1275,14 @@ static void explore_load_view(explore_state_t *state, const char* path)
|
||||
state->view_op [lvl] = valid_op;
|
||||
state->view_cats [lvl] = cat;
|
||||
state->view_use_split[lvl] = explore_by_info[cat].use_split;
|
||||
if (lvl == lvl_max)
|
||||
state->view_levels++;
|
||||
if (lvl == lvl_max) state->view_levels++;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (depth == 1 && type == RJSON_OBJECT_END)
|
||||
{
|
||||
op = ((uint8_t)-1);
|
||||
}
|
||||
}
|
||||
rjson_free(json);
|
||||
intfstream_close(file);
|
||||
@ -1302,20 +1300,16 @@ unsigned menu_displaylist_explore(file_list_t *list, settings_t *settings)
|
||||
file_list_t *menu_stack = MENU_LIST_GET(menu_list, 0);
|
||||
struct item_file *stack_top = menu_stack->list;
|
||||
size_t depth = menu_stack->size;
|
||||
unsigned current_type = 0;
|
||||
unsigned previous_type = 0;
|
||||
unsigned current_type = (depth > 0 ? stack_top[depth - 1].type : 0);
|
||||
unsigned previous_type = (depth > 1 ? stack_top[depth - 2].type : 0);
|
||||
unsigned current_cat = current_type - EXPLORE_TYPE_FIRSTCATEGORY;
|
||||
|
||||
if (depth > 0)
|
||||
if (depth > 1)
|
||||
{
|
||||
current_type = stack_top[depth - 1].type;
|
||||
/* Overwrite the menu title function with our custom one */
|
||||
/* Depth 1 is never popped so we can only do this on sub menus */
|
||||
if (depth > 1)
|
||||
{
|
||||
previous_type = stack_top[depth - 2].type;
|
||||
((menu_file_list_cbs_t*)stack_top[depth - 1].actiondata)
|
||||
->action_get_title = explore_action_get_title;
|
||||
}
|
||||
/* overwrite the menu title function with our custom one */
|
||||
/* depth 1 is never popped so we can only do this on sub menus */
|
||||
((menu_file_list_cbs_t*)stack_top[depth - 1].actiondata)
|
||||
->action_get_title = explore_action_get_title;
|
||||
}
|
||||
|
||||
if (!state)
|
||||
@ -1330,357 +1324,360 @@ unsigned menu_displaylist_explore(file_list_t *list, settings_t *settings)
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_EXPLORE_INITIALISING_LIST),
|
||||
MENU_ENUM_LABEL_EXPLORE_INITIALISING_LIST,
|
||||
FILE_TYPE_NONE, 0, 0, NULL);
|
||||
|
||||
return (unsigned)list->size;
|
||||
}
|
||||
else
|
||||
|
||||
/* check if we are opening a saved view */
|
||||
if (current_type == MENU_SETTING_HORIZONTAL_MENU || current_type == MENU_EXPLORE_TAB)
|
||||
{
|
||||
unsigned current_cat = current_type - EXPLORE_TYPE_FIRSTCATEGORY;
|
||||
/* check if we are opening a saved view */
|
||||
if (current_type == MENU_SETTING_HORIZONTAL_MENU || current_type == MENU_EXPLORE_TAB)
|
||||
const char* view_path = explore_get_view_path(menu_st, menu_list, menu_stack);
|
||||
if (view_path)
|
||||
{
|
||||
const char* view_path = explore_get_view_path(menu_st, menu_list, menu_stack);
|
||||
if (view_path)
|
||||
{
|
||||
explore_load_view(state, view_path);
|
||||
current_type = EXPLORE_TYPE_VIEW;
|
||||
}
|
||||
explore_load_view(state, view_path);
|
||||
current_type = EXPLORE_TYPE_VIEW;
|
||||
}
|
||||
}
|
||||
|
||||
/* clear any filter remaining from showing a view on the horizontal menu */
|
||||
if (current_type == MENU_EXPLORE_TAB)
|
||||
/* clear any filter remaining from showing a view on the horizontal menu */
|
||||
if (current_type == MENU_EXPLORE_TAB)
|
||||
{
|
||||
state->view_levels = 0;
|
||||
state->view_search[0] = '\0';
|
||||
}
|
||||
|
||||
/* clear title string */
|
||||
state->title[0] = '\0';
|
||||
|
||||
/* append filtered categories to title */
|
||||
for (i = 0; i != state->view_levels; i++)
|
||||
{
|
||||
unsigned cat = state->view_cats[i];
|
||||
explore_string_t **entries = state->by[cat];
|
||||
explore_string_t* match = state->view_match[i];
|
||||
explore_append_title(state, "%s%s: ", (i ? " / " : ""),
|
||||
msg_hash_to_str(explore_by_info[cat].name_enum));
|
||||
switch (state->view_op[i])
|
||||
{
|
||||
state->view_levels = 0;
|
||||
state->view_search[0] = '\0';
|
||||
case EXPLORE_OP_EQUAL:
|
||||
explore_append_title(state, "%s", (match ? match->str
|
||||
: msg_hash_to_str(MENU_ENUM_LABEL_VALUE_UNKNOWN)));
|
||||
break;
|
||||
case EXPLORE_OP_MIN:
|
||||
explore_append_title(state, "%s - %s",
|
||||
entries[state->view_idx_min[i]]->str,
|
||||
entries[RBUF_LEN(entries)-1]->str);
|
||||
break;
|
||||
case EXPLORE_OP_MAX:
|
||||
explore_append_title(state, "%s - %s",
|
||||
entries[0]->str,
|
||||
entries[state->view_idx_max[i]]->str);
|
||||
break;
|
||||
case EXPLORE_OP_RANGE:
|
||||
explore_append_title(state, "%s - %s",
|
||||
entries[state->view_idx_min[i]]->str,
|
||||
entries[state->view_idx_max[i]]->str);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* clear title string */
|
||||
state->title[0] = '\0';
|
||||
/* append string search to title */
|
||||
if (*state->view_search)
|
||||
explore_append_title(state, "%s%s: '%s'",
|
||||
(state->view_levels ? " / " : ""),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_NAME),
|
||||
state->view_search);
|
||||
|
||||
/* append filtered categories to title */
|
||||
for (i = 0; i != state->view_levels; i++)
|
||||
{
|
||||
unsigned cat = state->view_cats[i];
|
||||
explore_string_t **entries = state->by[cat];
|
||||
explore_string_t* match = state->view_match[i];
|
||||
explore_append_title(state, "%s%s: ", (i ? " / " : ""),
|
||||
msg_hash_to_str(explore_by_info[cat].name_enum));
|
||||
switch (state->view_op[i])
|
||||
{
|
||||
case EXPLORE_OP_EQUAL:
|
||||
explore_append_title(state, "%s", (match ? match->str
|
||||
: msg_hash_to_str(MENU_ENUM_LABEL_VALUE_UNKNOWN)));
|
||||
break;
|
||||
case EXPLORE_OP_MIN:
|
||||
explore_append_title(state, "%s - %s",
|
||||
entries[state->view_idx_min[i]]->str,
|
||||
entries[RBUF_LEN(entries)-1]->str);
|
||||
break;
|
||||
case EXPLORE_OP_MAX:
|
||||
explore_append_title(state, "%s - %s",
|
||||
entries[0]->str,
|
||||
entries[state->view_idx_max[i]]->str);
|
||||
break;
|
||||
case EXPLORE_OP_RANGE:
|
||||
explore_append_title(state, "%s - %s",
|
||||
entries[state->view_idx_min[i]]->str,
|
||||
entries[state->view_idx_max[i]]->str);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* append string search to title */
|
||||
if (*state->view_search)
|
||||
explore_append_title(state, "%s%s: '%s'",
|
||||
(state->view_levels ? " / " : ""),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_RDB_ENTRY_NAME),
|
||||
state->view_search);
|
||||
|
||||
state->show_icons = (current_cat == EXPLORE_BY_SYSTEM)
|
||||
state->show_icons = (current_cat == EXPLORE_BY_SYSTEM)
|
||||
? EXPLORE_ICONS_SYSTEM_CATEGORY
|
||||
: (current_type >= EXPLORE_TYPE_FIRSTITEM)
|
||||
? EXPLORE_ICONS_CONTENT
|
||||
: EXPLORE_ICONS_OFF;
|
||||
? EXPLORE_ICONS_CONTENT
|
||||
: EXPLORE_ICONS_OFF;
|
||||
|
||||
if ( current_type == MENU_EXPLORE_TAB
|
||||
|| current_type == EXPLORE_TYPE_ADDITIONALFILTER)
|
||||
if ( current_type == MENU_EXPLORE_TAB
|
||||
|| current_type == EXPLORE_TYPE_ADDITIONALFILTER)
|
||||
{
|
||||
/* Explore top or selecting an additional filter category */
|
||||
unsigned cat;
|
||||
bool is_top = (current_type == MENU_EXPLORE_TAB);
|
||||
if (is_top)
|
||||
strlcpy(state->title,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_EXPLORE_TAB),
|
||||
sizeof(state->title));
|
||||
else
|
||||
explore_append_title(state, " / %s",
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_EXPLORE_ADDITIONAL_FILTER));
|
||||
|
||||
if (!*state->view_search)
|
||||
{
|
||||
/* Explore top or selecting an additional filter category */
|
||||
unsigned cat;
|
||||
bool is_top = (current_type == MENU_EXPLORE_TAB);
|
||||
if (is_top)
|
||||
strlcpy(state->title,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_EXPLORE_TAB),
|
||||
sizeof(state->title));
|
||||
else
|
||||
explore_append_title(state, " / %s",
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_EXPLORE_ADDITIONAL_FILTER));
|
||||
explore_menu_entry(
|
||||
list, state,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_EXPLORE_SEARCH_NAME),
|
||||
EXPLORE_TYPE_SEARCH, explore_action_ok_find);
|
||||
if (list->size)
|
||||
((menu_file_list_cbs_t*)list->list[list->size-1].actiondata)->action_sublabel = explore_action_sublabel_spacer;
|
||||
}
|
||||
|
||||
if (!*state->view_search)
|
||||
for (cat = 0; cat < EXPLORE_CAT_COUNT; cat++)
|
||||
{
|
||||
explore_string_t **entries = state->by[cat];
|
||||
if (!RBUF_LEN(entries))
|
||||
continue;
|
||||
|
||||
/* don't list already filtered categories unless it can be filtered by range */
|
||||
for (i = 0; i != state->view_levels; i++)
|
||||
if (state->view_cats[i] == cat)
|
||||
break;
|
||||
|
||||
if (i == state->view_levels || (i == state->view_levels - 1
|
||||
&& state->view_op[i] == EXPLORE_OP_EQUAL
|
||||
&& !explore_by_info[cat].is_boolean
|
||||
&& RBUF_LEN(state->by[cat]) > 1))
|
||||
{
|
||||
explore_menu_entry(
|
||||
list, state,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_EXPLORE_SEARCH_NAME),
|
||||
EXPLORE_TYPE_SEARCH, explore_action_ok_find);
|
||||
if (list->size)
|
||||
((menu_file_list_cbs_t*)list->list[list->size-1].actiondata)->action_sublabel = explore_action_sublabel_spacer;
|
||||
}
|
||||
size_t tmplen = strlcpy(tmp,
|
||||
msg_hash_to_str(explore_by_info[cat].by_enum), sizeof(tmp));
|
||||
|
||||
for (cat = 0; cat < EXPLORE_CAT_COUNT; cat++)
|
||||
{
|
||||
explore_string_t **entries = state->by[cat];
|
||||
if (!RBUF_LEN(entries))
|
||||
continue;
|
||||
|
||||
/* don't list already filtered categories unless it can be filtered by range */
|
||||
for (i = 0; i != state->view_levels; i++)
|
||||
if (state->view_cats[i] == cat)
|
||||
break;
|
||||
|
||||
if (i == state->view_levels || (i == state->view_levels - 1
|
||||
&& state->view_op[i] == EXPLORE_OP_EQUAL
|
||||
&& !explore_by_info[cat].is_boolean
|
||||
&& RBUF_LEN(state->by[cat]) > 1))
|
||||
if (is_top)
|
||||
{
|
||||
strlcpy(tmp, msg_hash_to_str(explore_by_info[cat].by_enum),
|
||||
sizeof(tmp));
|
||||
|
||||
if (is_top)
|
||||
{
|
||||
size_t tmplen = strlcat(tmp, " (", sizeof(tmp));
|
||||
if (explore_by_info[cat].is_numeric)
|
||||
{
|
||||
strlcat(tmp, entries[0]->str, sizeof(tmp));
|
||||
strlcat(tmp, " - ", sizeof(tmp));
|
||||
strlcat(tmp, entries[RBUF_LEN(entries) - 1]->str, sizeof(tmp));
|
||||
}
|
||||
else if (!explore_by_info[cat].is_boolean)
|
||||
snprintf(tmp + tmplen + 2, sizeof(tmp) - tmplen - 2,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_EXPLORE_ITEMS_COUNT),
|
||||
(unsigned)RBUF_LEN(entries));
|
||||
strlcat(tmp, ")", sizeof(tmp));
|
||||
}
|
||||
else if (i != state->view_levels)
|
||||
if (explore_by_info[cat].is_numeric)
|
||||
snprintf(tmp + tmplen, sizeof(tmp) - tmplen, " (%s - %s)",
|
||||
entries[0]->str, entries[RBUF_LEN(entries) - 1]->str);
|
||||
else if (!explore_by_info[cat].is_boolean)
|
||||
{
|
||||
strlcat(tmp, " (", sizeof(tmp));
|
||||
strlcat(tmp, msg_hash_to_str(MENU_ENUM_LABEL_EXPLORE_RANGE_FILTER), sizeof(tmp));
|
||||
snprintf(tmp + tmplen + 2, sizeof(tmp) - tmplen - 2,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_EXPLORE_ITEMS_COUNT),
|
||||
(unsigned)RBUF_LEN(entries));
|
||||
strlcat(tmp, ")", sizeof(tmp));
|
||||
}
|
||||
|
||||
explore_menu_entry(list, state,
|
||||
tmp, cat + EXPLORE_TYPE_FIRSTCATEGORY, explore_action_ok);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_top)
|
||||
{
|
||||
if (list->size)
|
||||
((menu_file_list_cbs_t*)list->list[list->size-1].actiondata)->action_sublabel = explore_action_sublabel_spacer;
|
||||
explore_menu_entry(list, state,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_EXPLORE_SHOW_ALL),
|
||||
EXPLORE_TYPE_SHOWALL, explore_action_ok);
|
||||
}
|
||||
}
|
||||
else if ((!state->view_levels && !*state->view_search
|
||||
&& current_cat < EXPLORE_CAT_COUNT))
|
||||
{
|
||||
/* Unfiltered list of all items in a selected explore by category */
|
||||
explore_string_t **entries = state->by[current_cat];
|
||||
size_t i_last = RBUF_LEN(entries) - 1;
|
||||
for (i = 0; i <= i_last; i++)
|
||||
explore_menu_entry(list, state,
|
||||
entries[i]->str, EXPLORE_TYPE_FIRSTITEM + i, explore_action_ok);
|
||||
|
||||
if (state->has_unknown[current_cat])
|
||||
{
|
||||
if (list->size)
|
||||
((menu_file_list_cbs_t*)list->list[list->size-1].actiondata)->action_sublabel = explore_action_sublabel_spacer;
|
||||
explore_menu_entry(list, state,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_UNKNOWN),
|
||||
EXPLORE_TYPE_FILTERNULL, explore_action_ok);
|
||||
}
|
||||
|
||||
explore_append_title(state, "%s",
|
||||
msg_hash_to_str(explore_by_info[current_cat].by_enum));
|
||||
}
|
||||
else if (current_type < EXPLORE_TYPE_FIRSTITEM
|
||||
|| (previous_type >= EXPLORE_TYPE_FIRSTCATEGORY
|
||||
&& previous_type < EXPLORE_TYPE_FIRSTITEM))
|
||||
{
|
||||
unsigned view_levels = state->view_levels;
|
||||
char* view_search = state->view_search;
|
||||
uint8_t* view_op = state->view_op;
|
||||
bool* view_use_split = state->view_use_split;
|
||||
unsigned* view_cats = state->view_cats;
|
||||
explore_string_t** view_match = state->view_match;
|
||||
uint32_t* view_idx_min = state->view_idx_min;
|
||||
uint32_t* view_idx_max = state->view_idx_max;
|
||||
explore_entry_t* entries = state->entries, *e, *eend;
|
||||
bool* map_filtered_category = NULL;
|
||||
bool has_search = !!*view_search;
|
||||
bool is_show_all = (!view_levels && !has_search);
|
||||
bool is_filtered_category = (current_cat < EXPLORE_CAT_COUNT);
|
||||
bool filtered_category_have_unknown = false;
|
||||
size_t first_list_entry;
|
||||
|
||||
if (is_show_all)
|
||||
explore_append_title(state,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_EXPLORE_ALL));
|
||||
|
||||
if (is_filtered_category)
|
||||
{
|
||||
/* List filtered items in a selected explore by category */
|
||||
if (!view_levels || view_cats[view_levels - 1] != current_cat)
|
||||
explore_append_title(state, " / %s",
|
||||
msg_hash_to_str(explore_by_info[current_cat].by_enum));
|
||||
else
|
||||
else if (i != state->view_levels)
|
||||
{
|
||||
/* List all items again when setting a range filter */
|
||||
explore_append_title(state, " (%s)",
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_EXPLORE_RANGE_FILTER));
|
||||
view_levels--;
|
||||
strlcat(tmp, " (", sizeof(tmp));
|
||||
strlcat(tmp, msg_hash_to_str(MENU_ENUM_LABEL_EXPLORE_RANGE_FILTER), sizeof(tmp));
|
||||
strlcat(tmp, ")", sizeof(tmp));
|
||||
}
|
||||
}
|
||||
else if (current_type == EXPLORE_TYPE_VIEW)
|
||||
{
|
||||
/* Show a saved view */
|
||||
state->show_icons = EXPLORE_ICONS_CONTENT;
|
||||
|
||||
explore_menu_entry(list, state,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_EXPLORE_DELETE_VIEW),
|
||||
EXPLORE_TYPE_VIEW, explore_action_ok_deleteview);
|
||||
if (list->size)
|
||||
((menu_file_list_cbs_t*)list->list[list->size-1].actiondata)->action_sublabel = explore_action_sublabel_spacer;
|
||||
tmp, cat + EXPLORE_TYPE_FIRSTCATEGORY, explore_action_ok);
|
||||
}
|
||||
}
|
||||
|
||||
if (is_top)
|
||||
{
|
||||
if (list->size)
|
||||
((menu_file_list_cbs_t*)list->list[list->size-1].actiondata)->action_sublabel = explore_action_sublabel_spacer;
|
||||
explore_menu_entry(list, state,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_EXPLORE_SHOW_ALL),
|
||||
EXPLORE_TYPE_SHOWALL, explore_action_ok);
|
||||
}
|
||||
}
|
||||
else if ((!state->view_levels && !*state->view_search
|
||||
&& current_cat < EXPLORE_CAT_COUNT))
|
||||
{
|
||||
/* Unfiltered list of all items in a selected explore by category */
|
||||
explore_string_t **entries = state->by[current_cat];
|
||||
size_t i_last = RBUF_LEN(entries) - 1;
|
||||
for (i = 0; i <= i_last; i++)
|
||||
explore_menu_entry(list, state,
|
||||
entries[i]->str, EXPLORE_TYPE_FIRSTITEM + i, explore_action_ok);
|
||||
|
||||
if (state->has_unknown[current_cat])
|
||||
{
|
||||
if (list->size)
|
||||
((menu_file_list_cbs_t*)list->list[list->size-1].actiondata)->action_sublabel = explore_action_sublabel_spacer;
|
||||
explore_menu_entry(list, state,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_UNKNOWN),
|
||||
EXPLORE_TYPE_FILTERNULL, explore_action_ok);
|
||||
}
|
||||
|
||||
explore_append_title(state, "%s",
|
||||
msg_hash_to_str(explore_by_info[current_cat].by_enum));
|
||||
}
|
||||
else if (current_type < EXPLORE_TYPE_FIRSTITEM
|
||||
|| (previous_type >= EXPLORE_TYPE_FIRSTCATEGORY
|
||||
&& previous_type < EXPLORE_TYPE_FIRSTITEM))
|
||||
{
|
||||
unsigned view_levels = state->view_levels;
|
||||
char* view_search = state->view_search;
|
||||
uint8_t* view_op = state->view_op;
|
||||
bool* view_use_split = state->view_use_split;
|
||||
unsigned* view_cats = state->view_cats;
|
||||
explore_string_t** view_match = state->view_match;
|
||||
uint32_t* view_idx_min = state->view_idx_min;
|
||||
uint32_t* view_idx_max = state->view_idx_max;
|
||||
explore_entry_t* entries = state->entries, *e, *eend;
|
||||
bool* map_filtered_category = NULL;
|
||||
bool has_search = !!*view_search;
|
||||
bool is_show_all = (!view_levels && !has_search);
|
||||
bool is_filtered_category = (current_cat < EXPLORE_CAT_COUNT);
|
||||
bool filtered_category_have_unknown = false;
|
||||
size_t first_list_entry;
|
||||
|
||||
if (is_show_all)
|
||||
{
|
||||
explore_append_title(state,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_EXPLORE_ALL));
|
||||
}
|
||||
|
||||
if (is_filtered_category)
|
||||
{
|
||||
/* List filtered items in a selected explore by category */
|
||||
if (!view_levels || view_cats[view_levels - 1] != current_cat)
|
||||
{
|
||||
explore_append_title(state, " / %s",
|
||||
msg_hash_to_str(explore_by_info[current_cat].by_enum));
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Game list */
|
||||
state->show_icons = EXPLORE_ICONS_CONTENT;
|
||||
explore_menu_entry(list, state,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_EXPLORE_ADD_ADDITIONAL_FILTER),
|
||||
EXPLORE_TYPE_ADDITIONALFILTER, explore_action_ok);
|
||||
explore_menu_entry(list, state,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_EXPLORE_SAVE_VIEW),
|
||||
EXPLORE_TYPE_VIEW, explore_action_ok_saveview);
|
||||
if (list->size)
|
||||
((menu_file_list_cbs_t*)list->list[list->size-1].actiondata)->action_sublabel = explore_action_sublabel_spacer;
|
||||
/* List all items again when setting a range filter */
|
||||
explore_append_title(state, " (%s)",
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_EXPLORE_RANGE_FILTER));
|
||||
view_levels--;
|
||||
}
|
||||
|
||||
first_list_entry = list->size;
|
||||
for (e = entries, eend = RBUF_END(entries); e != eend; e++)
|
||||
{
|
||||
for (i = 0; i != view_levels; i++)
|
||||
{
|
||||
explore_string_t* eby = e->by[view_cats[i]];
|
||||
switch (view_op[i])
|
||||
{
|
||||
case EXPLORE_OP_EQUAL:
|
||||
if (view_match[i] == eby)
|
||||
continue;
|
||||
if (view_use_split[i] && e->split)
|
||||
{
|
||||
explore_string_t** split = e->split;
|
||||
do
|
||||
{
|
||||
if (*split == view_match[i])
|
||||
break;
|
||||
} while (*(++split));
|
||||
if (*split)
|
||||
continue;
|
||||
}
|
||||
goto SKIP_ENTRY;
|
||||
case EXPLORE_OP_MIN:
|
||||
if (eby && eby->idx >= view_idx_min[i])
|
||||
continue;
|
||||
goto SKIP_ENTRY;
|
||||
case EXPLORE_OP_MAX:
|
||||
if (eby && eby->idx <= view_idx_max[i])
|
||||
continue;
|
||||
goto SKIP_ENTRY;
|
||||
case EXPLORE_OP_RANGE:
|
||||
if (eby && eby->idx >= view_idx_min[i]
|
||||
&& eby->idx <= view_idx_max[i])
|
||||
continue;
|
||||
goto SKIP_ENTRY;
|
||||
}
|
||||
}
|
||||
|
||||
if (has_search && !strcasestr(e->playlist_entry->label, view_search))
|
||||
goto SKIP_ENTRY;
|
||||
|
||||
if (is_filtered_category)
|
||||
{
|
||||
explore_string_t* str = e->by[current_cat];
|
||||
if (!str)
|
||||
{
|
||||
filtered_category_have_unknown = true;
|
||||
continue;
|
||||
}
|
||||
if (RHMAP_HAS(map_filtered_category, str->idx + 1))
|
||||
continue;
|
||||
RHMAP_SET(map_filtered_category, str->idx + 1, true);
|
||||
explore_menu_entry(list, state, str->str,
|
||||
EXPLORE_TYPE_FIRSTITEM + str->idx, explore_action_ok);
|
||||
}
|
||||
#ifdef EXPLORE_SHOW_ORIGINAL_TITLE
|
||||
else if (e->original_title)
|
||||
explore_menu_entry(list, state, e->original_title,
|
||||
EXPLORE_TYPE_FIRSTITEM + (e - entries), explore_action_ok);
|
||||
#endif
|
||||
else
|
||||
explore_menu_entry(list, state, e->playlist_entry->label,
|
||||
EXPLORE_TYPE_FIRSTITEM + (e - entries), explore_action_ok);
|
||||
SKIP_ENTRY:;
|
||||
}
|
||||
|
||||
if (is_filtered_category)
|
||||
qsort(list->list, list->size, sizeof(*list->list), explore_qsort_func_menulist);
|
||||
|
||||
explore_append_title(state,
|
||||
" (%u)", (unsigned)(list->size - first_list_entry));
|
||||
|
||||
if (is_filtered_category && filtered_category_have_unknown)
|
||||
{
|
||||
if (list->size)
|
||||
((menu_file_list_cbs_t*)list->list[list->size-1].actiondata)->action_sublabel = explore_action_sublabel_spacer;
|
||||
explore_menu_entry(list, state,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_UNKNOWN),
|
||||
EXPLORE_TYPE_FILTERNULL, explore_action_ok);
|
||||
}
|
||||
|
||||
RHMAP_FREE(map_filtered_category);
|
||||
}
|
||||
else if (current_type == EXPLORE_TYPE_VIEW)
|
||||
{
|
||||
/* Show a saved view */
|
||||
state->show_icons = EXPLORE_ICONS_CONTENT;
|
||||
explore_menu_entry(list, state,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_EXPLORE_DELETE_VIEW),
|
||||
EXPLORE_TYPE_VIEW, explore_action_ok_deleteview);
|
||||
if (list->size)
|
||||
((menu_file_list_cbs_t*)list->list[list->size-1].actiondata)->action_sublabel = explore_action_sublabel_spacer;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Content page of selected game */
|
||||
int pl_idx;
|
||||
const struct playlist_entry *pl_entry =
|
||||
state->entries[current_type - EXPLORE_TYPE_FIRSTITEM].playlist_entry;
|
||||
/* Game list */
|
||||
state->show_icons = EXPLORE_ICONS_CONTENT;
|
||||
explore_menu_entry(list, state,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_EXPLORE_ADD_ADDITIONAL_FILTER),
|
||||
EXPLORE_TYPE_ADDITIONALFILTER, explore_action_ok);
|
||||
explore_menu_entry(list, state,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_EXPLORE_SAVE_VIEW),
|
||||
EXPLORE_TYPE_VIEW, explore_action_ok_saveview);
|
||||
if (list->size)
|
||||
((menu_file_list_cbs_t*)list->list[list->size-1].actiondata)->action_sublabel = explore_action_sublabel_spacer;
|
||||
}
|
||||
|
||||
strlcpy(state->title,
|
||||
pl_entry->label, sizeof(state->title));
|
||||
|
||||
for (pl_idx = 0; pl_idx != RBUF_LEN(state->playlists); pl_idx++)
|
||||
first_list_entry = list->size;
|
||||
for (e = entries, eend = RBUF_END(entries); e != eend; e++)
|
||||
{
|
||||
for (i = 0; i != view_levels; i++)
|
||||
{
|
||||
menu_displaylist_info_t info;
|
||||
const struct playlist_entry *pl_first = NULL;
|
||||
playlist_t *pl = state->playlists[pl_idx];
|
||||
|
||||
playlist_get_index(pl, 0, &pl_first);
|
||||
|
||||
if ( (pl_entry < pl_first)
|
||||
|| (pl_entry >= pl_first + playlist_size(pl)))
|
||||
continue;
|
||||
|
||||
/* Fake all the state so the content screen
|
||||
* and information screen think we're viewing via playlist */
|
||||
menu_displaylist_info_init(&info);
|
||||
playlist_set_cached_external(pl);
|
||||
menu->rpl_entry_selection_ptr = (unsigned)(pl_entry - pl_first);
|
||||
strlcpy(menu->deferred_path,
|
||||
pl_entry->path, sizeof(menu->deferred_path));
|
||||
info.list = list;
|
||||
menu_displaylist_ctl(DISPLAYLIST_HORIZONTAL_CONTENT_ACTIONS, &info,
|
||||
settings);
|
||||
break;
|
||||
explore_string_t* eby = e->by[view_cats[i]];
|
||||
switch (view_op[i])
|
||||
{
|
||||
case EXPLORE_OP_EQUAL:
|
||||
if (view_match[i] == eby)
|
||||
continue;
|
||||
if (view_use_split[i] && e->split)
|
||||
{
|
||||
explore_string_t** split = e->split;
|
||||
do
|
||||
{
|
||||
if (*split == view_match[i])
|
||||
break;
|
||||
} while (*(++split));
|
||||
if (*split)
|
||||
continue;
|
||||
}
|
||||
goto SKIP_ENTRY;
|
||||
case EXPLORE_OP_MIN:
|
||||
if (eby && eby->idx >= view_idx_min[i])
|
||||
continue;
|
||||
goto SKIP_ENTRY;
|
||||
case EXPLORE_OP_MAX:
|
||||
if (eby && eby->idx <= view_idx_max[i])
|
||||
continue;
|
||||
goto SKIP_ENTRY;
|
||||
case EXPLORE_OP_RANGE:
|
||||
if (eby && eby->idx >= view_idx_min[i]
|
||||
&& eby->idx <= view_idx_max[i])
|
||||
continue;
|
||||
goto SKIP_ENTRY;
|
||||
}
|
||||
}
|
||||
|
||||
if (has_search && !strcasestr(e->playlist_entry->label, view_search))
|
||||
goto SKIP_ENTRY;
|
||||
|
||||
if (is_filtered_category)
|
||||
{
|
||||
explore_string_t* str = e->by[current_cat];
|
||||
if (!str)
|
||||
{
|
||||
filtered_category_have_unknown = true;
|
||||
continue;
|
||||
}
|
||||
if (RHMAP_HAS(map_filtered_category, str->idx + 1))
|
||||
continue;
|
||||
RHMAP_SET(map_filtered_category, str->idx + 1, true);
|
||||
explore_menu_entry(list, state, str->str,
|
||||
EXPLORE_TYPE_FIRSTITEM + str->idx, explore_action_ok);
|
||||
}
|
||||
#ifdef EXPLORE_SHOW_ORIGINAL_TITLE
|
||||
else if (e->original_title)
|
||||
explore_menu_entry(list, state, e->original_title,
|
||||
EXPLORE_TYPE_FIRSTITEM + (e - entries), explore_action_ok);
|
||||
#endif
|
||||
else
|
||||
explore_menu_entry(list, state, e->playlist_entry->label,
|
||||
EXPLORE_TYPE_FIRSTITEM + (e - entries), explore_action_ok);
|
||||
SKIP_ENTRY:;
|
||||
}
|
||||
|
||||
if (is_filtered_category)
|
||||
qsort(list->list, list->size, sizeof(*list->list), explore_qsort_func_menulist);
|
||||
|
||||
explore_append_title(state,
|
||||
" (%u)", (unsigned)(list->size - first_list_entry));
|
||||
|
||||
if (is_filtered_category && filtered_category_have_unknown)
|
||||
{
|
||||
if (list->size)
|
||||
((menu_file_list_cbs_t*)list->list[list->size-1].actiondata)->action_sublabel = explore_action_sublabel_spacer;
|
||||
explore_menu_entry(list, state,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_UNKNOWN),
|
||||
EXPLORE_TYPE_FILTERNULL, explore_action_ok);
|
||||
}
|
||||
|
||||
RHMAP_FREE(map_filtered_category);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Content page of selected game */
|
||||
int pl_idx;
|
||||
const struct playlist_entry *pl_entry =
|
||||
state->entries[current_type - EXPLORE_TYPE_FIRSTITEM].playlist_entry;
|
||||
|
||||
strlcpy(state->title,
|
||||
pl_entry->label, sizeof(state->title));
|
||||
|
||||
for (pl_idx = 0; pl_idx != RBUF_LEN(state->playlists); pl_idx++)
|
||||
{
|
||||
menu_displaylist_info_t info;
|
||||
const struct playlist_entry* pl_first = NULL;
|
||||
playlist_t *pl =
|
||||
state->playlists[pl_idx];
|
||||
|
||||
playlist_get_index(pl, 0, &pl_first);
|
||||
|
||||
if ( pl_entry < pl_first ||
|
||||
pl_entry >= pl_first + playlist_size(pl))
|
||||
continue;
|
||||
|
||||
/* Fake all the state so the content screen
|
||||
* and information screen think we're viewing via playlist */
|
||||
menu_displaylist_info_init(&info);
|
||||
playlist_set_cached_external(pl);
|
||||
menu->rpl_entry_selection_ptr = (unsigned)(pl_entry - pl_first);
|
||||
strlcpy(menu->deferred_path,
|
||||
pl_entry->path, sizeof(menu->deferred_path));
|
||||
info.list = list;
|
||||
menu_displaylist_ctl(DISPLAYLIST_HORIZONTAL_CONTENT_ACTIONS, &info,
|
||||
settings);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1690,27 +1687,22 @@ SKIP_ENTRY:;
|
||||
uintptr_t menu_explore_get_entry_icon(unsigned type)
|
||||
{
|
||||
unsigned i;
|
||||
explore_entry_t *e;
|
||||
if ( !explore_state
|
||||
|| !explore_state->show_icons
|
||||
if (!explore_state || !explore_state->show_icons
|
||||
|| type < EXPLORE_TYPE_FIRSTITEM)
|
||||
return 0;
|
||||
|
||||
i = (type - EXPLORE_TYPE_FIRSTITEM);
|
||||
|
||||
switch (explore_state->show_icons)
|
||||
if (explore_state->show_icons == EXPLORE_ICONS_CONTENT)
|
||||
{
|
||||
case EXPLORE_ICONS_CONTENT:
|
||||
e = &explore_state->entries[i];
|
||||
if (e < RBUF_END(explore_state->entries))
|
||||
return explore_state->icons[e->by[EXPLORE_BY_SYSTEM]->idx];
|
||||
break;
|
||||
case EXPLORE_ICONS_SYSTEM_CATEGORY:
|
||||
if (i < RBUF_LEN(explore_state->icons))
|
||||
return explore_state->icons[i];
|
||||
break;
|
||||
explore_entry_t* e = &explore_state->entries[i];
|
||||
if (e < RBUF_END(explore_state->entries))
|
||||
return explore_state->icons[e->by[EXPLORE_BY_SYSTEM]->idx];
|
||||
}
|
||||
else if (explore_state->show_icons == EXPLORE_ICONS_SYSTEM_CATEGORY)
|
||||
{
|
||||
if (i < RBUF_LEN(explore_state->icons))
|
||||
return explore_state->icons[i];
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user