diff --git a/config.def.h b/config.def.h index 550d93d997..71efaaea98 100644 --- a/config.def.h +++ b/config.def.h @@ -707,6 +707,10 @@ static const unsigned default_content_history_size = 100; /* File format to use when writing playlists to disk */ static const bool playlist_use_old_format = false; +/* Show currently associated core next to each playlist entry + * (RGUI only) */ +static const bool playlist_show_core_name = true; + /* Show Menu start-up screen on boot. */ static const bool default_menu_show_start_screen = true; diff --git a/configuration.c b/configuration.c index e0c1ef7767..f60752c548 100644 --- a/configuration.c +++ b/configuration.c @@ -1501,6 +1501,7 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings, SETTING_BOOL("rgui_background_filler_thickness_enable", &settings->bools.menu_rgui_background_filler_thickness_enable, true, true, false); SETTING_BOOL("rgui_border_filler_thickness_enable", &settings->bools.menu_rgui_border_filler_thickness_enable, true, true, false); SETTING_BOOL("rgui_border_filler_enable", &settings->bools.menu_rgui_border_filler_enable, true, true, false); + SETTING_BOOL("playlist_show_core_name", &settings->bools.playlist_show_core_name, true, playlist_show_core_name, false); #endif #ifdef HAVE_XMB SETTING_BOOL("xmb_shadows_enable", &settings->bools.menu_xmb_shadows_enable, true, xmb_shadows_enable, false); diff --git a/configuration.h b/configuration.h index c56b16ff5b..ed6561798b 100644 --- a/configuration.h +++ b/configuration.h @@ -308,6 +308,8 @@ typedef struct settings bool sustained_performance_mode; bool playlist_use_old_format; bool content_runtime_log; + + bool playlist_show_core_name; } bools; struct diff --git a/intl/msg_hash_lbl.h b/intl/msg_hash_lbl.h index 05399f3ef7..e8f942cae2 100644 --- a/intl/msg_hash_lbl.h +++ b/intl/msg_hash_lbl.h @@ -1783,3 +1783,5 @@ MSG_HASH(MENU_ENUM_LABEL_MENU_SOUND_BGM, "menu_sound_bgm") MSG_HASH(MENU_ENUM_LABEL_CONTENT_RUNTIME_LOG, "content_runtime_log") +MSG_HASH(MENU_ENUM_LABEL_PLAYLIST_SHOW_CORE_NAME, + "playlist_show_core_name") diff --git a/intl/msg_hash_us.h b/intl/msg_hash_us.h index 574150e13a..dde3743fb1 100644 --- a/intl/msg_hash_us.h +++ b/intl/msg_hash_us.h @@ -8230,6 +8230,14 @@ MSG_HASH( MENU_ENUM_LABEL_VALUE_PLAYLIST_USE_OLD_FORMAT, "Save playlists using old format" ) +MSG_HASH( + MENU_ENUM_LABEL_VALUE_PLAYLIST_SHOW_CORE_NAME, + "Show associated cores in playlists" + ) +MSG_HASH( + MENU_ENUM_SUBLABEL_PLAYLIST_SHOW_CORE_NAME, + "Labels each playlist entry with the currently associated core (if any)." + ) MSG_HASH( MENU_ENUM_LABEL_VALUE_MENU_SOUNDS, "Menu Sounds" diff --git a/menu/cbs/menu_cbs_sublabel.c b/menu/cbs/menu_cbs_sublabel.c index e01aa523d3..8fa16d7a7f 100644 --- a/menu/cbs/menu_cbs_sublabel.c +++ b/menu/cbs/menu_cbs_sublabel.c @@ -520,6 +520,7 @@ default_sublabel_macro(action_bind_sublabel_content_runtime_log, default_sublabel_macro(action_bind_sublabel_menu_rgui_internal_upscale_level, MENU_ENUM_SUBLABEL_MENU_RGUI_INTERNAL_UPSCALE_LEVEL) default_sublabel_macro(action_bind_sublabel_menu_ticker_type, MENU_ENUM_SUBLABEL_MENU_TICKER_TYPE) default_sublabel_macro(action_bind_sublabel_menu_ticker_speed, MENU_ENUM_SUBLABEL_MENU_TICKER_SPEED) +default_sublabel_macro(action_bind_sublabel_playlist_show_core_name, MENU_ENUM_SUBLABEL_PLAYLIST_SHOW_CORE_NAME) static int action_bind_sublabel_systeminfo_controller_entry( file_list_t *list, @@ -2264,6 +2265,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs, case MENU_ENUM_LABEL_MENU_TICKER_SPEED: BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_ticker_speed); break; + case MENU_ENUM_LABEL_PLAYLIST_SHOW_CORE_NAME: + BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_playlist_show_core_name); + break; default: case MSG_UNKNOWN: return -1; diff --git a/menu/drivers/rgui.c b/menu/drivers/rgui.c index b3fc998396..ede7fd4ce5 100644 --- a/menu/drivers/rgui.c +++ b/menu/drivers/rgui.c @@ -417,12 +417,12 @@ typedef struct char *msgbox; unsigned color_theme; rgui_colors_t colors; - bool is_playlist_entry; + bool is_playlist; + bool entry_has_thumbnail; bool show_thumbnail; char *thumbnail_system; char *thumbnail_content; char *thumbnail_path; - char *thumbnail_playlist; uint32_t thumbnail_queue_size; bool show_wallpaper; char theme_preset_path[PATH_MAX_LENGTH]; /* Must be a fixed length array... */ @@ -649,13 +649,13 @@ static void process_wallpaper(rgui_t *rgui, struct texture_image *image) rgui->force_redraw = true; } -static void request_thumbnail(rgui_t *rgui, const char *path) +static bool request_thumbnail(rgui_t *rgui, const char *path) { /* Do nothing if current thumbnail path hasn't changed */ if (!string_is_empty(path) && !string_is_empty(thumbnail.path)) { if (string_is_equal(thumbnail.path, path)) - return; + return true; } /* 'Reset' current thumbnail */ @@ -676,9 +676,12 @@ static void request_thumbnail(rgui_t *rgui, const char *path) if(task_push_image_load(thumbnail.path, menu_display_handle_thumbnail_upload, NULL)) { rgui->thumbnail_queue_size++; + return true; } } } + + return false; } static bool downscale_thumbnail(rgui_t *rgui, struct texture_image *image_src, struct texture_image *image_dst) @@ -1308,7 +1311,7 @@ static void rgui_render_background(rgui_t *rgui) } /* Skip drawing border if we are currently showing a thumbnail */ - if (!(rgui->show_thumbnail && rgui->is_playlist_entry && (thumbnail.is_valid || (rgui->thumbnail_queue_size > 0)))) + if (!(rgui->show_thumbnail && rgui->entry_has_thumbnail && (thumbnail.is_valid || (rgui->thumbnail_queue_size > 0)))) { if (rgui_framebuf_data) { @@ -1596,7 +1599,7 @@ static void rgui_render(void *data, bool is_idle) * this is better than switching back to the text playlist * view, which causes ugly flickering when scrolling quickly * through a list...) */ - if (rgui->show_thumbnail && rgui->is_playlist_entry && (thumbnail.is_valid || (rgui->thumbnail_queue_size > 0))) + if (rgui->show_thumbnail && rgui->entry_has_thumbnail && (thumbnail.is_valid || (rgui->thumbnail_queue_size > 0))) { char thumbnail_title_buf[255]; unsigned title_x, title_width; @@ -1632,6 +1635,15 @@ static void rgui_render(void *data, bool is_idle) unsigned timedate_x = RGUI_TERM_WIDTH(fb_width) * FONT_WIDTH_STRIDE - RGUI_TERM_START_X(fb_width); unsigned core_name_len = ((timedate_x - RGUI_TERM_START_X(fb_width)) / FONT_WIDTH_STRIDE) - 3; bool show_core_name = settings->bools.menu_core_enable; + bool show_playlist_labels = !settings->bools.playlist_show_core_name && rgui->is_playlist; + playlist_t *playlist = NULL; + + /* Get cached playlist, if required */ + if (show_playlist_labels) + { + playlist = playlist_get_cached(); + show_playlist_labels = show_playlist_labels && playlist; + } /* Print title */ title_buf[0] = '\0'; @@ -1671,7 +1683,8 @@ static void rgui_render(void *data, bool is_idle) size_t entry_title_buf_utf8len = 0; size_t entry_title_buf_len = 0; bool has_value = false; - bool entry_selected = menu_entry_is_currently_selected((unsigned)i); + bool entry_selected = menu_entry_is_currently_selected((unsigned)i); + bool show_playlist_label = show_playlist_labels; size_t selection = menu_navigation_get_selection(); if (i > (selection + 100)) @@ -1686,13 +1699,49 @@ static void rgui_render(void *data, bool is_idle) menu_entry_init(&entry); menu_entry_get(&entry, 0, (unsigned)i, NULL, true); - /* Read entry parameters */ - entry_spacing = menu_entry_get_spacing(&entry); - menu_entry_get_value(&entry, entry_value, sizeof(entry_value)); - entry_path = menu_entry_get_rich_label(&entry); + /* Get playlist label for current entry, if required */ + if (show_playlist_label) + { + /* Ensure that we fallback to the normal entry label if + * any of the following playlist access fails... */ + show_playlist_label = false; - /* Determine whether entry has a value component */ - has_value = !string_is_empty(entry_value); + if (i < playlist_get_size(playlist)) + { + const char *playlist_label = NULL; + playlist_get_index(playlist, i, NULL, &playlist_label, NULL, NULL, NULL, NULL); + + if (!string_is_empty(playlist_label)) + { + entry_path = strdup(playlist_label); + show_playlist_label = true; + } + } + } + + if (show_playlist_label) + { + /* We are using the current playlist label as the entry title + * > We already have entry_path + * > entry_spacing is irrelevant (set to zero) + * > entry_value is irrelevant + * > has_value is false */ + entry_spacing = 0; + has_value = false; + } + else + { + /* Either this is not a playlist entry, or we are ignoring + * playlists - extract all required info from entry itself */ + + /* Read entry parameters */ + entry_spacing = menu_entry_get_spacing(&entry); + menu_entry_get_value(&entry, entry_value, sizeof(entry_value)); + entry_path = menu_entry_get_rich_label(&entry); + + /* Determine whether entry has a value component */ + has_value = !string_is_empty(entry_value); + } /* Format entry title string */ entry_title_max_len = RGUI_TERM_WIDTH(fb_width) - (1 + 2); @@ -1943,8 +1992,6 @@ static void rgui_free(void *data) free(rgui->thumbnail_content); if (!string_is_empty(rgui->thumbnail_path)) free(rgui->thumbnail_path); - if (!string_is_empty(rgui->thumbnail_playlist)) - free(rgui->thumbnail_playlist); } fb_font_inited = menu_display_get_font_data_init(); @@ -2106,7 +2153,7 @@ static const char *rgui_thumbnail_ident(void) return msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF); } -static void rgui_update_thumbnail_path(void *userdata) +static bool rgui_update_thumbnail_path(void *userdata) { rgui_t *rgui = (rgui_t*)userdata; settings_t *settings = config_get_ptr(); @@ -2173,75 +2220,74 @@ static void rgui_update_thumbnail_path(void *userdata) strlcat(new_path, file_path_str(FILE_PATH_PNG_EXTENSION), sizeof(new_path)); if (!string_is_empty(new_path)) + { rgui->thumbnail_path = strdup(new_path); + return true; + } } } } } + + return false; } static void rgui_set_thumbnail_system(void *userdata, char *s, size_t len) { rgui_t *rgui = (rgui_t*)userdata; - char tmp_path[PATH_MAX_LENGTH] = {0}; if (!rgui) return; if (!string_is_empty(rgui->thumbnail_system)) free(rgui->thumbnail_system); - if (!string_is_empty(rgui->thumbnail_playlist)) - free(rgui->thumbnail_playlist); rgui->thumbnail_system = strdup(s); - /* Get associated playlist file name - * (i.e. thumbnail_system>.lpl) */ - if (!string_is_empty(rgui->thumbnail_system)) - { - strlcpy(tmp_path, rgui->thumbnail_system, sizeof(tmp_path)); - strlcat(tmp_path, file_path_str(FILE_PATH_LPL_EXTENSION), sizeof(tmp_path)); - if (!string_is_empty(tmp_path)) - rgui->thumbnail_playlist = strdup(tmp_path); - } } -static void rgui_update_thumbnail_content(void *userdata) +static bool rgui_update_thumbnail_content(void *userdata) { rgui_t *rgui = (rgui_t*)userdata; playlist_t *playlist = NULL; size_t selection = menu_navigation_get_selection(); if (!rgui) - return; + return false; - /* Check whether current selection is a playlist entry - * (i.e. whether we should be looking for a thumbnail image) */ - rgui->is_playlist_entry = false; - if (!string_is_empty(rgui->thumbnail_playlist)) + /* Get label of currently selected playlist entry */ + playlist = playlist_get_cached(); + if (playlist) { - if (string_is_equal(path_basename(rgui->menu_title), rgui->thumbnail_playlist)) + if (selection < playlist_get_size(playlist)) { - /* Get label of currently selected playlist entry - * > This is pretty nasty, but I can't see any other way of doing - * it (entry.path gives us almost what we need, but it's tainted - * with the core name, which is too difficult to remove...) */ - playlist = playlist_get_cached(); - if (playlist) + const char *label = NULL; + playlist_get_index(playlist, selection, NULL, &label, NULL, NULL, NULL, NULL); + + if (!string_is_empty(rgui->thumbnail_content)) { - if (selection < playlist_get_size(playlist)) - { - const char *label = NULL; - playlist_get_index(playlist, selection, NULL, &label, NULL, NULL, NULL, NULL); + free(rgui->thumbnail_content); + rgui->thumbnail_content = NULL; + } - if (!string_is_empty(rgui->thumbnail_content)) - { - free(rgui->thumbnail_content); - rgui->thumbnail_content = NULL; - } + if (!string_is_empty(label)) + { + rgui->thumbnail_content = strdup(label); + return true; + } + } + } + + return false; +} - if (!string_is_empty(label)) - { - rgui->thumbnail_content = strdup(label); - rgui->is_playlist_entry = true; - } - } +static void rgui_scan_selected_entry_thumbnail(rgui_t *rgui) +{ + rgui->entry_has_thumbnail = false; + + if (rgui->show_thumbnail && rgui->is_playlist) + { + if (rgui_update_thumbnail_content(rgui)) + { + if (rgui_update_thumbnail_path(rgui)) + { + rgui->entry_has_thumbnail = request_thumbnail(rgui, rgui->thumbnail_path); } } } @@ -2255,15 +2301,7 @@ static void rgui_update_thumbnail_image(void *userdata) rgui->show_thumbnail = !rgui->show_thumbnail; - if (rgui->show_thumbnail) - { - rgui_update_thumbnail_content(rgui); - if (rgui->is_playlist_entry) - { - rgui_update_thumbnail_path(rgui); - request_thumbnail(rgui, rgui->thumbnail_path); - } - } + rgui_scan_selected_entry_thumbnail(rgui); } static void rgui_navigation_set(void *data, bool scroll) @@ -2278,15 +2316,7 @@ static void rgui_navigation_set(void *data, bool scroll) if (!rgui) return; - if (rgui->show_thumbnail) - { - rgui_update_thumbnail_content(rgui); - if (rgui->is_playlist_entry) - { - rgui_update_thumbnail_path(rgui); - request_thumbnail(rgui, rgui->thumbnail_path); - } - } + rgui_scan_selected_entry_thumbnail(rgui); if (!scroll) return; @@ -2340,6 +2370,10 @@ static void rgui_populate_entries(void *data, return; menu_entries_get_title(rgui->menu_title, sizeof(rgui->menu_title)); + + /* Check whether we are currently viewing a playlist */ + rgui->is_playlist = string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_PLAYLIST_LIST)); + rgui_navigation_set(data, true); } diff --git a/menu/menu_displaylist.c b/menu/menu_displaylist.c index e711424915..dd7d325de3 100644 --- a/menu/menu_displaylist.c +++ b/menu/menu_displaylist.c @@ -5280,6 +5280,9 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist ret = menu_displaylist_parse_settings_enum(menu, info, MENU_ENUM_LABEL_PLAYLIST_USE_OLD_FORMAT, PARSE_ONLY_BOOL, false); + ret = menu_displaylist_parse_settings_enum(menu, info, + MENU_ENUM_LABEL_PLAYLIST_SHOW_CORE_NAME, + PARSE_ONLY_BOOL, false); menu_displaylist_parse_playlist_associations(info); info->need_push = true; diff --git a/menu/menu_setting.c b/menu/menu_setting.c index 0c43c93e7c..bdb8f5b46d 100644 --- a/menu/menu_setting.c +++ b/menu/menu_setting.c @@ -9777,6 +9777,25 @@ static bool setting_append_list( SD_FLAG_NONE ); + if (string_is_equal(settings->arrays.menu_driver, "rgui")) + { + CONFIG_BOOL( + list, list_info, + &settings->bools.playlist_show_core_name, + MENU_ENUM_LABEL_PLAYLIST_SHOW_CORE_NAME, + MENU_ENUM_LABEL_VALUE_PLAYLIST_SHOW_CORE_NAME, + playlist_show_core_name, + 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 + ); + } + END_SUB_GROUP(list, list_info, parent_group); END_GROUP(list, list_info, parent_group); diff --git a/msg_hash.h b/msg_hash.h index 12c6a6ff4b..f8b2dfa45f 100644 --- a/msg_hash.h +++ b/msg_hash.h @@ -2272,6 +2272,8 @@ enum msg_hash_enums MENU_ENUM_LABEL_VALUE_VIDEO_DRIVER_FALLBACK, MENU_LABEL(CONTENT_RUNTIME_LOG), + MENU_LABEL(PLAYLIST_SHOW_CORE_NAME), + MSG_LAST };