diff --git a/menu/disp/xmb.c b/menu/disp/xmb.c index d83f48be14..6512054fb6 100644 --- a/menu/disp/xmb.c +++ b/menu/disp/xmb.c @@ -90,6 +90,7 @@ typedef struct xmb_handle struct xmb_texture_item textures[XMB_TEXTURE_LAST]; int icon_size; float x; + float categories_x; float alpha; float arrow_alpha; float hspacing; @@ -580,15 +581,6 @@ static xmb_node_t* xmb_node_for_core(int i) if (!xmb) return NULL; - char mediapath[PATH_MAX], themepath[PATH_MAX], iconpath[PATH_MAX], - core_id[PATH_MAX], texturepath[PATH_MAX], content_texturepath[PATH_MAX]; - - fill_pathname_join(mediapath, g_settings.assets_directory, - "lakka", sizeof(mediapath)); - fill_pathname_join(themepath, mediapath, XMB_THEME, sizeof(themepath)); - fill_pathname_join(iconpath, themepath, xmb->icon_dir, sizeof(iconpath)); - fill_pathname_slash(iconpath, sizeof(iconpath)); - info_list = (core_info_list_t*)g_extern.core_info; info = NULL; @@ -614,27 +606,8 @@ static xmb_node_t* xmb_node_for_core(int i) node = (xmb_node_t*)info->userdata; - if (info->systemname) - { - char *tmp = xmb_str_replace(info->systemname, "/", " "); - strlcpy(core_id, tmp, sizeof(core_id)); - free(tmp); - } - else - strlcpy(core_id, "default", sizeof(core_id)); - - strlcpy(texturepath, iconpath, sizeof(texturepath)); - strlcat(texturepath, core_id, sizeof(texturepath)); - strlcat(texturepath, ".png", sizeof(texturepath)); - - strlcpy(content_texturepath, iconpath, sizeof(content_texturepath)); - strlcat(content_texturepath, core_id, sizeof(content_texturepath)); - strlcat(content_texturepath, "-content.png", sizeof(content_texturepath)); - node->alpha = i + 1 == xmb->active_category ? xmb->c_active_alpha : xmb->c_passive_alpha; node->zoom = i + 1 == xmb->active_category ? xmb->c_active_zoom : xmb->c_passive_zoom; - node->icon = xmb_png_texture_load(texturepath); - node->content_icon = xmb_png_texture_load(content_texturepath); } return node; @@ -751,7 +724,7 @@ static void xmb_populate_entries(void *data, const char *path, add_tween(XMB_DELAY, iz, &node->zoom, &inOutQuad, NULL); } - add_tween(XMB_DELAY, xmb->hspacing*-(float)driver.menu->cat_selection_ptr, &xmb->x, &inOutQuad, NULL); + add_tween(XMB_DELAY, xmb->hspacing*-(float)driver.menu->cat_selection_ptr, &xmb->categories_x, &inOutQuad, NULL); dir = driver.menu->cat_selection_ptr > driver.menu->cat_selection_ptr_old ? 1 : -1; xmb_list_switch_old(driver.menu->menu_list->selection_buf_old, dir, driver.menu->selection_ptr_old); xmb_list_switch_new(driver.menu->menu_list->selection_buf, dir, driver.menu->selection_ptr); @@ -835,6 +808,9 @@ static void xmb_draw_items(file_list_t *list, file_list_t *stack, icon = xmb->textures[XMB_TEXTURE_FILE].id; break; case MENU_FILE_PLAYLIST_ENTRY: + icon = xmb->textures[XMB_TEXTURE_FILE].id; + break; + case MENU_FILE_CONTENTLIST_ENTRY: icon = core_node ? core_node->content_icon : xmb->textures[XMB_TEXTURE_FILE].id; break; case MENU_FILE_CARCHIVE: @@ -968,7 +944,7 @@ static void xmb_frame(void) continue; xmb_draw_icon(node->icon, - xmb->x + xmb->margin_left + xmb->hspacing*(i+1) - xmb->icon_size / 2.0, + xmb->x + xmb->categories_x + xmb->margin_left + xmb->hspacing*(i+1) - xmb->icon_size / 2.0, xmb->margin_top + xmb->icon_size / 2.0, node->alpha, 0, @@ -1054,6 +1030,7 @@ static void *xmb_init(void) xmb->active_category = 0; xmb->active_category_old = 0; xmb->x = 0; + xmb->categories_x = 0; xmb->alpha = 1.0f; xmb->arrow_alpha = 0; xmb->depth = 1; @@ -1143,12 +1120,16 @@ static bool xmb_font_init_first(const gl_font_renderer_t **font_driver, static void xmb_context_reset(void *data) { - int k; + int i, k; char bgpath[PATH_MAX]; - char mediapath[PATH_MAX], themepath[PATH_MAX], iconpath[PATH_MAX], fontpath[PATH_MAX]; + char mediapath[PATH_MAX], themepath[PATH_MAX], iconpath[PATH_MAX], + fontpath[PATH_MAX], core_id[PATH_MAX], texturepath[PATH_MAX], + content_texturepath[PATH_MAX]; + gl_t *gl = NULL; xmb_handle_t *xmb = NULL; menu_handle_t *menu = (menu_handle_t*)data; + xmb_node_t *node = NULL; if (!menu) return; @@ -1219,6 +1200,50 @@ static void xmb_context_reset(void *data) xmb->settings_node.icon = xmb->textures[XMB_TEXTURE_SETTINGS].id; xmb->settings_node.alpha = xmb->c_active_alpha; xmb->settings_node.zoom = xmb->c_active_zoom; + + core_info_list_t* info_list = (core_info_list_t*)g_extern.core_info; + core_info_t* info = NULL; + + if (!info_list) + return; + + for (i = 1; i < xmb->num_categories; i++) + { + node = xmb_node_for_core(i-1); + + fill_pathname_join(mediapath, g_settings.assets_directory, + "lakka", sizeof(mediapath)); + fill_pathname_join(themepath, mediapath, XMB_THEME, sizeof(themepath)); + fill_pathname_join(iconpath, themepath, xmb->icon_dir, sizeof(iconpath)); + fill_pathname_slash(iconpath, sizeof(iconpath)); + + info = (core_info_t*)&info_list->list[i-1]; + + if (!info) + continue; + + if (info->systemname) + { + char *tmp = xmb_str_replace(info->systemname, "/", " "); + strlcpy(core_id, tmp, sizeof(core_id)); + free(tmp); + } + else + strlcpy(core_id, "default", sizeof(core_id)); + + strlcpy(texturepath, iconpath, sizeof(texturepath)); + strlcat(texturepath, core_id, sizeof(texturepath)); + strlcat(texturepath, ".png", sizeof(texturepath)); + + strlcpy(content_texturepath, iconpath, sizeof(content_texturepath)); + strlcat(content_texturepath, core_id, sizeof(content_texturepath)); + strlcat(content_texturepath, "-content.png", sizeof(content_texturepath)); + + node->alpha = i == xmb->active_category ? xmb->c_active_alpha : xmb->c_passive_alpha; + node->zoom = i == xmb->active_category ? xmb->c_active_zoom : xmb->c_passive_zoom; + node->icon = xmb_png_texture_load(texturepath); + node->content_icon = xmb_png_texture_load(content_texturepath); + } } static void xmb_navigation_clear(void *data, bool pending_push) diff --git a/menu/menu_common.h b/menu/menu_common.h index f4b72abfef..3c73362a66 100644 --- a/menu/menu_common.h +++ b/menu/menu_common.h @@ -65,6 +65,7 @@ typedef enum MENU_FILE_DEVICE, MENU_FILE_CORE, MENU_FILE_PLAYLIST_ENTRY, + MENU_FILE_CONTENTLIST_ENTRY, MENU_FILE_SHADER_PRESET, MENU_FILE_SHADER, MENU_FILE_VIDEOFILTER, @@ -80,6 +81,7 @@ typedef enum MENU_SETTING_ACTION, MENU_SETTING_GROUP, MENU_SETTING_SUBGROUP, + MENU_SETTING_HORIZONTAL_MENU, MENU_FILE_TYPE_T_LAST, } menu_file_type_t; diff --git a/menu/menu_entries.c b/menu/menu_entries.c index 6374fcf257..89ddde2269 100644 --- a/menu/menu_entries.c +++ b/menu/menu_entries.c @@ -163,6 +163,73 @@ int entries_push_main_menu_list(menu_handle_t *menu, return 0; } +static void content_list_push(void *data, core_info_t *info, const char* path) +{ + int num_items, j; + struct string_list *list = NULL; + file_list_t *flist = (file_list_t*)data; + + if (!info) + return; + + list = (struct string_list*)dir_list_new(path, info->supported_extensions, true); + + dir_list_sort(list, true); + + num_items = list ? list->size : 0; + + for (j = 0; j < num_items; j++) + { + if (list->elems[j].attr.i == RARCH_DIRECTORY) // is a directory + content_list_push(flist, info, list->elems[j].data); + else + menu_list_push( + flist, + path_basename(list->elems[j].data), + "content_actions", + MENU_FILE_CONTENTLIST_ENTRY, + 0); + } + + string_list_free(list); +} + +int entries_push_horizontal_menu_list(menu_handle_t *menu, + file_list_t *list, + const char *path, const char *label, + unsigned menu_type) +{ + menu_list_clear(list); + + core_info_t *info = NULL; + core_info_list_t *info_list = NULL; + + info_list = (core_info_list_t*)g_extern.core_info; + info = NULL; + + if (!info_list) + return -1; + + info = (core_info_t*)&info_list->list[driver.menu->cat_selection_ptr - 1]; + + if (!info) + return -1; + + if (!info->supports_no_game) + content_list_push(list, info, g_settings.content_directory); + else + menu_list_push(list, info->display_name, "", MENU_FILE_CONTENTLIST_ENTRY, 0); + + driver.menu->scroll_indices_size = 0; + menu_entries_build_scroll_indices(list); + menu_entries_refresh(list); + + if (driver.menu_ctx && driver.menu_ctx->populate_entries) + driver.menu_ctx->populate_entries(menu, path, label, menu_type); + + return 0; +} + int menu_entries_parse_list(file_list_t *list, file_list_t *menu_list, const char *dir, const char *label, unsigned type, unsigned default_type_plain, const char *exts) @@ -398,6 +465,8 @@ int menu_entries_deferred_push(file_list_t *list, file_list_t *menu_list) if (!strcmp(label, "Main Menu")) return entries_push_main_menu_list(driver.menu, list, path, label, type); + else if (!strcmp(label, "Horizontal Menu")) + return entries_push_horizontal_menu_list(driver.menu, list, path, label, type); cbs = (menu_file_list_cbs_t*) menu_list_get_last_stack_actiondata(driver.menu->menu_list); diff --git a/menu/menu_entries.h b/menu/menu_entries.h index ae7f747462..936edcc697 100644 --- a/menu/menu_entries.h +++ b/menu/menu_entries.h @@ -45,6 +45,11 @@ int entries_push_main_menu_list(menu_handle_t *menu, const char *path, const char *label, unsigned menu_type); +int entries_push_horizontal_menu_list(menu_handle_t *menu, + file_list_t *list, + const char *path, const char *label, + unsigned menu_type); + #ifdef __cplusplus } #endif diff --git a/menu/menu_entries_cbs.c b/menu/menu_entries_cbs.c index c6ec2fd00d..2501770696 100644 --- a/menu/menu_entries_cbs.c +++ b/menu/menu_entries_cbs.c @@ -209,6 +209,21 @@ static int action_ok_playlist_entry(const char *path, return -1; } +static int action_ok_contentlist_entry(const char *path, + const char *label, unsigned type, size_t idx) +{ + if (!driver.menu) + return -1; + + menu_list_push_stack_refresh( + driver.menu->menu_list, + "", + label, + type, + driver.menu->selection_ptr); + return 0; +} + static int action_ok_push_history_list(const char *path, const char *label, unsigned type, size_t idx) { @@ -972,6 +987,19 @@ static int action_toggle_mainmenu(unsigned type, const char *label, driver.menu->cat_selection_ptr_old = driver.menu->cat_selection_ptr; driver.menu->cat_selection_ptr += action == MENU_ACTION_LEFT ? -1 : 1; driver.menu->selection_ptr = 0; + + size_t stack_size = driver.menu->menu_list->menu_stack->size; + if (driver.menu->cat_selection_ptr == 0) + { + strlcpy(driver.menu->menu_list->menu_stack->list[stack_size-1].label, "Main Menu", PATH_MAX); + driver.menu->menu_list->menu_stack->list[stack_size-1].type = MENU_SETTINGS; + } + else + { + strlcpy(driver.menu->menu_list->menu_stack->list[stack_size-1].label, "Horizontal Menu", PATH_MAX); + driver.menu->menu_list->menu_stack->list[stack_size-1].type = MENU_SETTING_HORIZONTAL_MENU; + } + if (cbs && cbs->action_content_list_switch) return cbs->action_content_list_switch( driver.menu->menu_list->selection_buf, @@ -1827,30 +1855,27 @@ static int deferred_push_history_list(void *data, void *userdata, return 0; } -static void content_list_push(void *data, core_info_t *info, const char* path) +static int deferred_push_content_actions(void *data, void *userdata, + const char *path, const char *label, unsigned type) { - int num_items, j; - struct string_list *list = NULL; - file_list_t *flist = (file_list_t*)data; + unsigned i; + file_list_t *list = (file_list_t*)data; - if (!info) - return; + if (!list || !driver.menu) + return -1; - list = (struct string_list*)dir_list_new(path, info->supported_extensions, true); + menu_list_clear(list); - dir_list_sort(list, true); + menu_list_push(list, "Run", "", MENU_FILE_PLAIN, 0); - num_items = list ? list->size : 0; + driver.menu->scroll_indices_size = 0; + menu_entries_build_scroll_indices(list); + menu_entries_refresh(list); - for (j = 0; j < num_items; j++) - { - if (list->elems[j].attr.i == RARCH_DIRECTORY) // is a directory - content_list_push(flist, info, list->elems[j].data); - else - menu_list_push(flist, path_basename(list->elems[j].data), "", MENU_FILE_PLAYLIST_ENTRY, 0); - } + if (driver.menu_ctx && driver.menu_ctx->populate_entries) + driver.menu_ctx->populate_entries(driver.menu, path, label, type); - string_list_free(list); + return 0; } static int deferred_push_content_list(void *data, void *userdata, @@ -1861,43 +1886,13 @@ static int deferred_push_content_list(void *data, void *userdata, if (!list || !driver.menu) return -1; + menu_navigation_clear(driver.menu, true); if (driver.menu->cat_selection_ptr == 0) - { - menu_navigation_clear(driver.menu, true); - entries_push_main_menu_list(driver.menu, driver.menu->menu_list->selection_buf, + return entries_push_main_menu_list(driver.menu, driver.menu->menu_list->selection_buf, "", "Main Menu", 0); - return 0; - } - - menu_list_clear(list); - - core_info_t *info = NULL; - core_info_list_t *info_list = NULL; - - info_list = (core_info_list_t*)g_extern.core_info; - info = NULL; - - if (!info_list) - return -1; - - info = (core_info_t*)&info_list->list[driver.menu->cat_selection_ptr - 1]; - - if (!info) - return -1; - - if (!info->supports_no_game) - content_list_push(list, info, g_settings.content_directory); else - menu_list_push(list, info->display_name, "", MENU_FILE_PLAYLIST_ENTRY, 0); - - driver.menu->scroll_indices_size = 0; - menu_entries_build_scroll_indices(list); - menu_entries_refresh(list); - - if (driver.menu_ctx && driver.menu_ctx->populate_entries) - driver.menu_ctx->populate_entries(driver.menu, path, label, type); - - return 0; + return entries_push_horizontal_menu_list(driver.menu, driver.menu->menu_list->selection_buf, + "", "Horizontal Menu", 0); } static int deferred_push_configurations(void *data, void *userdata, @@ -2102,6 +2097,9 @@ static int menu_entries_cbs_init_bind_ok_first(menu_file_list_cbs_t *cbs, case MENU_FILE_PLAYLIST_ENTRY: cbs->action_ok = action_ok_playlist_entry; break; + case MENU_FILE_CONTENTLIST_ENTRY: + cbs->action_ok = action_ok_contentlist_entry; + break; case MENU_FILE_SHADER_PRESET: cbs->action_ok = action_ok_shader_preset_load; break; @@ -2326,7 +2324,7 @@ static void menu_entries_cbs_init_bind_toggle(menu_file_list_cbs_t *cbs, case MENU_FILE_USE_DIRECTORY: cbs->action_toggle = action_toggle_scroll; break; - case MENU_FILE_PLAYLIST_ENTRY: + case MENU_FILE_CONTENTLIST_ENTRY: cbs->action_toggle = action_toggle_mainmenu; break; } @@ -2347,6 +2345,8 @@ static void menu_entries_cbs_init_bind_deferred_push(menu_file_list_cbs_t *cbs, if (!strcmp(label, "history_list")) cbs->action_deferred_push = deferred_push_history_list; + else if (!strcmp(label, "content_actions")) + cbs->action_deferred_push = deferred_push_content_actions; else if (!strcmp(label, "Shader Options")) cbs->action_deferred_push = deferred_push_shader_options; else if (type == MENU_SETTING_GROUP)