mirror of
https://github.com/libretro/RetroArch
synced 2025-03-01 16:13:40 +00:00
(RGUI/XMB) Enable thumbnail display on mixed content playlists (history, favourites, etc.)
Move thumbnail path handling code to reusable menu_thumbnail_path.h/.c file (XMB) Bug fixes: - Show thumbnails correctly when 'Show associated cores in playlists' is enabled - Prevent each thumbnail from being loaded twice (!) when changing current selection
This commit is contained in:
parent
8064672f11
commit
28bb7c67af
@ -792,7 +792,8 @@ ifeq ($(HAVE_MENU_COMMON), 1)
|
||||
menu/menu_displaylist.o \
|
||||
menu/menu_animation.o \
|
||||
menu/drivers/menu_generic.o \
|
||||
menu/drivers/null.o
|
||||
menu/drivers/null.o \
|
||||
menu/menu_thumbnail_path.o
|
||||
|
||||
ifeq ($(HAVE_MENU_COMMON),1)
|
||||
OBJ += menu/drivers_display/menu_display_null.o
|
||||
|
@ -1238,6 +1238,7 @@ MENU
|
||||
#include "../menu/menu_shader.c"
|
||||
#include "../menu/menu_displaylist.c"
|
||||
#include "../menu/menu_animation.c"
|
||||
#include "../menu/menu_thumbnail_path.c"
|
||||
|
||||
#include "../menu/drivers/null.c"
|
||||
#include "../menu/drivers/menu_generic.c"
|
||||
|
@ -53,6 +53,7 @@
|
||||
#include <file/config_file.h>
|
||||
|
||||
/* Thumbnail additions */
|
||||
#include "../menu_thumbnail_path.h"
|
||||
#include <streams/file_stream.h>
|
||||
#include "../../tasks/tasks_internal.h"
|
||||
#include <gfx/scaler/scaler.h>
|
||||
@ -424,9 +425,7 @@ typedef struct
|
||||
bool is_playlist;
|
||||
bool entry_has_thumbnail;
|
||||
bool show_thumbnail;
|
||||
char *thumbnail_system;
|
||||
char *thumbnail_content;
|
||||
char *thumbnail_path;
|
||||
menu_thumbnail_path_data_t *thumbnail_path_data;
|
||||
uint32_t thumbnail_queue_size;
|
||||
bool show_wallpaper;
|
||||
char theme_preset_path[PATH_MAX_LENGTH]; /* Must be a fixed length array... */
|
||||
@ -1608,6 +1607,7 @@ static void rgui_render(void *data, bool is_idle)
|
||||
* through a list...) */
|
||||
if (rgui->show_thumbnail && rgui->entry_has_thumbnail && (thumbnail.is_valid || (rgui->thumbnail_queue_size > 0)))
|
||||
{
|
||||
const char *thumbnail_title = NULL;
|
||||
char thumbnail_title_buf[255];
|
||||
unsigned title_x, title_width;
|
||||
thumbnail_title_buf[0] = '\0';
|
||||
@ -1615,24 +1615,28 @@ static void rgui_render(void *data, bool is_idle)
|
||||
/* Draw thumbnail */
|
||||
rgui_render_thumbnail();
|
||||
|
||||
/* Format thumbnail title */
|
||||
ticker.s = thumbnail_title_buf;
|
||||
ticker.len = RGUI_TERM_WIDTH(fb_width) - 10;
|
||||
ticker.str = rgui->thumbnail_content;
|
||||
ticker.selected = true;
|
||||
menu_animation_ticker(&ticker);
|
||||
|
||||
title_width = utf8len(thumbnail_title_buf) * FONT_WIDTH_STRIDE;
|
||||
title_x = RGUI_TERM_START_X(fb_width) + ((RGUI_TERM_WIDTH(fb_width) * FONT_WIDTH_STRIDE) - title_width) / 2;
|
||||
|
||||
if (rgui_framebuf_data)
|
||||
/* Get thumbnail title */
|
||||
if (menu_thumbnail_get_label(rgui->thumbnail_path_data, &thumbnail_title))
|
||||
{
|
||||
/* Draw thumbnail title background */
|
||||
rgui_fill_rect(rgui, rgui_framebuf_data, fb_pitch,
|
||||
title_x - 5, 0, title_width + 10, FONT_HEIGHT_STRIDE, rgui_bg_filler);
|
||||
/* Format thumbnail title */
|
||||
ticker.s = thumbnail_title_buf;
|
||||
ticker.len = RGUI_TERM_WIDTH(fb_width) - 10;
|
||||
ticker.str = thumbnail_title;
|
||||
ticker.selected = true;
|
||||
menu_animation_ticker(&ticker);
|
||||
|
||||
/* Draw thumbnail title */
|
||||
blit_line((int)title_x, 0, thumbnail_title_buf, rgui->colors.hover_color);
|
||||
title_width = utf8len(thumbnail_title_buf) * FONT_WIDTH_STRIDE;
|
||||
title_x = RGUI_TERM_START_X(fb_width) + ((RGUI_TERM_WIDTH(fb_width) * FONT_WIDTH_STRIDE) - title_width) / 2;
|
||||
|
||||
if (rgui_framebuf_data)
|
||||
{
|
||||
/* Draw thumbnail title background */
|
||||
rgui_fill_rect(rgui, rgui_framebuf_data, fb_pitch,
|
||||
title_x - 5, 0, title_width + 10, FONT_HEIGHT_STRIDE, rgui_bg_filler);
|
||||
|
||||
/* Draw thumbnail title */
|
||||
blit_line((int)title_x, 0, thumbnail_title_buf, rgui->colors.hover_color);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -1927,6 +1931,10 @@ static void *rgui_init(void **userdata, bool video_is_threaded)
|
||||
rgui->last_width = fb_width;
|
||||
rgui->last_height = fb_height;
|
||||
|
||||
rgui->thumbnail_path_data = menu_thumbnail_path_init();
|
||||
if (!rgui->thumbnail_path_data)
|
||||
goto error;
|
||||
|
||||
rgui->thumbnail_queue_size = 0;
|
||||
/* Ensure that we start with thumbnails disabled */
|
||||
rgui->show_thumbnail = false;
|
||||
@ -1948,12 +1956,8 @@ static void rgui_free(void *data)
|
||||
|
||||
if (rgui)
|
||||
{
|
||||
if (!string_is_empty(rgui->thumbnail_system))
|
||||
free(rgui->thumbnail_system);
|
||||
if (!string_is_empty(rgui->thumbnail_content))
|
||||
free(rgui->thumbnail_content);
|
||||
if (!string_is_empty(rgui->thumbnail_path))
|
||||
free(rgui->thumbnail_path);
|
||||
if (rgui->thumbnail_path_data)
|
||||
free(rgui->thumbnail_path_data);
|
||||
}
|
||||
|
||||
fb_font_inited = menu_display_get_font_data_init();
|
||||
@ -2092,151 +2096,12 @@ static void rgui_navigation_clear(void *data, bool pending_push)
|
||||
rgui->scroll_y = 0;
|
||||
}
|
||||
|
||||
static const char *rgui_thumbnail_ident(void)
|
||||
{
|
||||
char folder = 0;
|
||||
settings_t *settings = config_get_ptr();
|
||||
|
||||
folder = settings->uints.menu_thumbnails;
|
||||
|
||||
switch (folder)
|
||||
{
|
||||
case 1:
|
||||
return "Named_Snaps";
|
||||
case 2:
|
||||
return "Named_Titles";
|
||||
case 3:
|
||||
return "Named_Boxarts";
|
||||
case 0:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF);
|
||||
}
|
||||
|
||||
static bool rgui_update_thumbnail_path(void *userdata)
|
||||
{
|
||||
rgui_t *rgui = (rgui_t*)userdata;
|
||||
settings_t *settings = config_get_ptr();
|
||||
char new_path[PATH_MAX_LENGTH] = {0};
|
||||
const char *thumbnail_base_dir = settings->paths.directory_thumbnails;
|
||||
const char *thumb_ident = rgui_thumbnail_ident();
|
||||
|
||||
if (!string_is_empty(rgui->thumbnail_path))
|
||||
{
|
||||
free(rgui->thumbnail_path);
|
||||
rgui->thumbnail_path = NULL;
|
||||
}
|
||||
|
||||
/* NB: The following is copied directly from xmb.c (xmb_update_thumbnail_path()) */
|
||||
if (!string_is_equal(thumb_ident, msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)) &&
|
||||
!string_is_empty(thumbnail_base_dir) &&
|
||||
!string_is_empty(rgui->thumbnail_system) &&
|
||||
!string_is_empty(rgui->thumbnail_content))
|
||||
{
|
||||
/* Append thumbnail system directory */
|
||||
fill_pathname_join(new_path, thumbnail_base_dir, rgui->thumbnail_system, sizeof(new_path));
|
||||
|
||||
if (!string_is_empty(new_path))
|
||||
{
|
||||
char *tmp_new2 = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
tmp_new2[0] = '\0';
|
||||
|
||||
/* Append Named_Snaps/Named_Boxarts/Named_Titles */
|
||||
fill_pathname_join(tmp_new2, new_path, thumb_ident, PATH_MAX_LENGTH * sizeof(char));
|
||||
|
||||
strlcpy(new_path, tmp_new2, PATH_MAX_LENGTH * sizeof(char));
|
||||
free(tmp_new2);
|
||||
tmp_new2 = NULL;
|
||||
|
||||
if (!string_is_empty(new_path))
|
||||
{
|
||||
/* Scrub characters that are not cross-platform and/or violate the
|
||||
* No-Intro filename standard:
|
||||
* http://datomatic.no-intro.org/stuff/The%20Official%20No-Intro%20Convention%20(20071030).zip
|
||||
* Replace these characters in the entry name with underscores.
|
||||
*/
|
||||
char *scrub_char_pointer = NULL;
|
||||
char *tmp_new = (char*)malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
char *tmp = strdup(rgui->thumbnail_content);
|
||||
|
||||
tmp_new[0] = '\0';
|
||||
|
||||
while((scrub_char_pointer = strpbrk(tmp, "&*/:`\"<>?\\|")))
|
||||
*scrub_char_pointer = '_';
|
||||
|
||||
fill_pathname_join(tmp_new, new_path, tmp, PATH_MAX_LENGTH * sizeof(char));
|
||||
|
||||
if (!string_is_empty(tmp_new))
|
||||
strlcpy(new_path, tmp_new, sizeof(new_path));
|
||||
|
||||
free(tmp_new);
|
||||
tmp_new = NULL;
|
||||
free(tmp);
|
||||
tmp = NULL;
|
||||
|
||||
/* Append png extension */
|
||||
if (!string_is_empty(new_path))
|
||||
{
|
||||
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;
|
||||
if (!rgui)
|
||||
return;
|
||||
if (!string_is_empty(rgui->thumbnail_system))
|
||||
free(rgui->thumbnail_system);
|
||||
rgui->thumbnail_system = strdup(s);
|
||||
}
|
||||
|
||||
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 false;
|
||||
|
||||
/* Get label of currently selected playlist entry */
|
||||
playlist = playlist_get_cached();
|
||||
if (playlist)
|
||||
{
|
||||
if (selection < playlist_get_size(playlist))
|
||||
{
|
||||
const char *label = NULL;
|
||||
playlist_get_index(playlist, selection, NULL, &label, NULL, NULL, NULL, 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;
|
||||
menu_thumbnail_set_system(rgui->thumbnail_path_data, s);
|
||||
}
|
||||
|
||||
static void rgui_scan_selected_entry_thumbnail(rgui_t *rgui)
|
||||
@ -2245,11 +2110,18 @@ static void rgui_scan_selected_entry_thumbnail(rgui_t *rgui)
|
||||
|
||||
if (rgui->show_thumbnail && rgui->is_playlist)
|
||||
{
|
||||
if (rgui_update_thumbnail_content(rgui))
|
||||
if (menu_thumbnail_set_content_playlist(rgui->thumbnail_path_data,
|
||||
playlist_get_cached(), menu_navigation_get_selection()))
|
||||
{
|
||||
if (rgui_update_thumbnail_path(rgui))
|
||||
if (menu_thumbnail_update_path(rgui->thumbnail_path_data, MENU_THUMBNAIL_RIGHT))
|
||||
{
|
||||
rgui->entry_has_thumbnail = request_thumbnail(rgui, rgui->thumbnail_path);
|
||||
const char *thumbnail_path = NULL;
|
||||
|
||||
if (menu_thumbnail_get_path(rgui->thumbnail_path_data,
|
||||
MENU_THUMBNAIL_RIGHT, &thumbnail_path))
|
||||
{
|
||||
rgui->entry_has_thumbnail = request_thumbnail(rgui, thumbnail_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2379,7 +2251,10 @@ static void rgui_populate_entries(void *data,
|
||||
return;
|
||||
|
||||
/* 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->is_playlist = string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_PLAYLIST_LIST)) ||
|
||||
string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_LOAD_CONTENT_HISTORY)) ||
|
||||
string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_FAVORITES_LIST)) ||
|
||||
string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_IMAGES_LIST));
|
||||
|
||||
/* Set menu title */
|
||||
menu_entries_get_title(rgui->menu_title, sizeof(rgui->menu_title));
|
||||
|
@ -45,6 +45,7 @@
|
||||
#include "../menu_animation.h"
|
||||
#include "../menu_entries.h"
|
||||
#include "../menu_input.h"
|
||||
#include "../menu_thumbnail_path.h"
|
||||
|
||||
#include "../../core_info.h"
|
||||
#include "../../core.h"
|
||||
@ -245,6 +246,8 @@ typedef struct xmb_handle
|
||||
bool mouse_show;
|
||||
bool use_ps3_layout;
|
||||
bool assets_missing;
|
||||
bool is_playlist;
|
||||
bool is_db_manager_list;
|
||||
|
||||
uint8_t system_tab_end;
|
||||
uint8_t tabs[XMB_SYSTEM_TAB_MAX_LENGTH];
|
||||
@ -306,11 +309,7 @@ typedef struct xmb_handle
|
||||
|
||||
char title_name[255];
|
||||
char *box_message;
|
||||
char *thumbnail_system;
|
||||
char *thumbnail_content;
|
||||
char *savestate_thumbnail_file_path;
|
||||
char *thumbnail_file_path;
|
||||
char *left_thumbnail_file_path;
|
||||
char *bg_file_path;
|
||||
|
||||
file_list_t *selection_buf_old;
|
||||
@ -340,6 +339,8 @@ typedef struct xmb_handle
|
||||
font_data_t *font2;
|
||||
video_font_raster_block_t raster_block;
|
||||
video_font_raster_block_t raster_block2;
|
||||
|
||||
menu_thumbnail_path_data_t *thumbnail_path_data;
|
||||
} xmb_handle_t;
|
||||
|
||||
float scale_mod[8] = {
|
||||
@ -559,32 +560,6 @@ static xmb_node_t *xmb_copy_node(const xmb_node_t *old_node)
|
||||
return new_node;
|
||||
}
|
||||
|
||||
static const char *xmb_thumbnails_ident(char pos)
|
||||
{
|
||||
char folder = 0;
|
||||
settings_t *settings = config_get_ptr();
|
||||
|
||||
if (pos == 'R')
|
||||
folder = settings->uints.menu_thumbnails;
|
||||
if (pos == 'L')
|
||||
folder = settings->uints.menu_left_thumbnails;
|
||||
|
||||
switch (folder)
|
||||
{
|
||||
case 1:
|
||||
return "Named_Snaps";
|
||||
case 2:
|
||||
return "Named_Titles";
|
||||
case 3:
|
||||
return "Named_Boxarts";
|
||||
case 0:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF);
|
||||
}
|
||||
|
||||
static float *xmb_gradient_ident(video_frame_info_t *video_info)
|
||||
{
|
||||
switch (video_info->xmb_color_theme)
|
||||
@ -952,153 +927,21 @@ end:
|
||||
|
||||
static void xmb_update_thumbnail_path(void *data, unsigned i, char pos)
|
||||
{
|
||||
menu_entry_t entry;
|
||||
unsigned entry_type = 0;
|
||||
char new_path[PATH_MAX_LENGTH] = {0};
|
||||
settings_t *settings = config_get_ptr();
|
||||
xmb_handle_t *xmb = (xmb_handle_t*)data;
|
||||
playlist_t *playlist = NULL;
|
||||
const char *dir_thumbnails = settings->paths.directory_thumbnails;
|
||||
xmb_handle_t *xmb = (xmb_handle_t*)data;
|
||||
const char *core_name = NULL;
|
||||
|
||||
menu_entry_init(&entry);
|
||||
if (!xmb)
|
||||
return;
|
||||
|
||||
if (!xmb || string_is_empty(dir_thumbnails))
|
||||
goto end;
|
||||
|
||||
menu_entry_get(&entry, 0, i, NULL, true);
|
||||
|
||||
entry_type = menu_entry_get_type_new(&entry);
|
||||
|
||||
if (entry_type == FILE_TYPE_IMAGEVIEWER || entry_type == FILE_TYPE_IMAGE)
|
||||
/* imageviewer content requires special treatment... */
|
||||
menu_thumbnail_get_core_name(xmb->thumbnail_path_data, &core_name);
|
||||
if (string_is_equal(core_name, "imageviewer"))
|
||||
{
|
||||
file_list_t *selection_buf = menu_entries_get_selection_buf_ptr(0);
|
||||
xmb_node_t *node = (xmb_node_t*)
|
||||
file_list_get_userdata_at_offset(selection_buf, i);
|
||||
|
||||
if (node && !string_is_empty(node->fullpath) &&
|
||||
(pos == 'R' || (pos == 'L' && string_is_equal(xmb_thumbnails_ident('R'),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)))))
|
||||
{
|
||||
if (!string_is_empty(entry.path))
|
||||
fill_pathname_join(
|
||||
new_path,
|
||||
node->fullpath,
|
||||
entry.path,
|
||||
sizeof(new_path));
|
||||
|
||||
goto end;
|
||||
}
|
||||
if ((pos == 'R') || (pos == 'L' && !menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT)))
|
||||
menu_thumbnail_update_path(xmb->thumbnail_path_data, pos == 'R' ? MENU_THUMBNAIL_RIGHT : MENU_THUMBNAIL_LEFT);
|
||||
}
|
||||
else if (filebrowser_get_type() != FILEBROWSER_NONE)
|
||||
{
|
||||
video_driver_texture_unload(&xmb->thumbnail);
|
||||
goto end;
|
||||
}
|
||||
|
||||
playlist = playlist_get_cached();
|
||||
|
||||
if (playlist)
|
||||
{
|
||||
const char *core_name = NULL;
|
||||
playlist_get_index(playlist, i,
|
||||
NULL, NULL, NULL, &core_name, NULL, NULL);
|
||||
|
||||
if (string_is_equal(core_name, "imageviewer"))
|
||||
{
|
||||
if (
|
||||
(pos == 'R') ||
|
||||
(
|
||||
pos == 'L' &&
|
||||
string_is_equal(xmb_thumbnails_ident('R'),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))
|
||||
)
|
||||
)
|
||||
{
|
||||
if (!string_is_empty(entry.label))
|
||||
strlcpy(new_path, entry.label,
|
||||
sizeof(new_path));
|
||||
}
|
||||
else
|
||||
video_driver_texture_unload(&xmb->left_thumbnail);
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
/* Append thumbnail system directory */
|
||||
if (!string_is_empty(xmb->thumbnail_system))
|
||||
fill_pathname_join(
|
||||
new_path,
|
||||
dir_thumbnails,
|
||||
xmb->thumbnail_system,
|
||||
sizeof(new_path));
|
||||
|
||||
if (!string_is_empty(new_path))
|
||||
{
|
||||
char *tmp_new2 = (char*)
|
||||
malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
|
||||
tmp_new2[0] = '\0';
|
||||
|
||||
/* Append Named_Snaps/Named_Boxarts/Named_Titles */
|
||||
if (pos == 'R')
|
||||
fill_pathname_join(tmp_new2, new_path,
|
||||
xmb_thumbnails_ident('R'), PATH_MAX_LENGTH * sizeof(char));
|
||||
if (pos == 'L')
|
||||
fill_pathname_join(tmp_new2, new_path,
|
||||
xmb_thumbnails_ident('L'), PATH_MAX_LENGTH * sizeof(char));
|
||||
|
||||
strlcpy(new_path, tmp_new2,
|
||||
PATH_MAX_LENGTH * sizeof(char));
|
||||
free(tmp_new2);
|
||||
}
|
||||
|
||||
/* Scrub characters that are not cross-platform and/or violate the
|
||||
* No-Intro filename standard:
|
||||
* http://datomatic.no-intro.org/stuff/The%20Official%20No-Intro%20Convention%20(20071030).zip
|
||||
* Replace these characters in the entry name with underscores.
|
||||
*/
|
||||
if (!string_is_empty(xmb->thumbnail_content))
|
||||
{
|
||||
char *scrub_char_pointer = NULL;
|
||||
char *tmp_new = (char*)
|
||||
malloc(PATH_MAX_LENGTH * sizeof(char));
|
||||
char *tmp = strdup(xmb->thumbnail_content);
|
||||
|
||||
tmp_new[0] = '\0';
|
||||
|
||||
while((scrub_char_pointer = strpbrk(tmp, "&*/:`\"<>?\\|")))
|
||||
*scrub_char_pointer = '_';
|
||||
|
||||
/* Look for thumbnail file with this scrubbed filename */
|
||||
|
||||
fill_pathname_join(tmp_new,
|
||||
new_path,
|
||||
tmp, PATH_MAX_LENGTH * sizeof(char));
|
||||
|
||||
if (!string_is_empty(tmp_new))
|
||||
strlcpy(new_path,
|
||||
tmp_new, sizeof(new_path));
|
||||
|
||||
free(tmp_new);
|
||||
free(tmp);
|
||||
}
|
||||
|
||||
/* Append png extension */
|
||||
if (!string_is_empty(new_path))
|
||||
strlcat(new_path,
|
||||
file_path_str(FILE_PATH_PNG_EXTENSION),
|
||||
sizeof(new_path));
|
||||
|
||||
end:
|
||||
if (xmb && !string_is_empty(new_path))
|
||||
{
|
||||
if (pos == 'R')
|
||||
xmb->thumbnail_file_path = strdup(new_path);
|
||||
if (pos == 'L')
|
||||
xmb->left_thumbnail_file_path = strdup(new_path);
|
||||
}
|
||||
|
||||
menu_entry_free(&entry);
|
||||
else
|
||||
menu_thumbnail_update_path(xmb->thumbnail_path_data, pos == 'R' ? MENU_THUMBNAIL_RIGHT : MENU_THUMBNAIL_LEFT);
|
||||
}
|
||||
|
||||
static void xmb_update_savestate_thumbnail_path(void *data, unsigned i)
|
||||
@ -1162,32 +1005,29 @@ static void xmb_update_savestate_thumbnail_path(void *data, unsigned i)
|
||||
|
||||
static void xmb_update_thumbnail_image(void *data)
|
||||
{
|
||||
xmb_handle_t *xmb = (xmb_handle_t*)data;
|
||||
xmb_handle_t *xmb = (xmb_handle_t*)data;
|
||||
const char *right_thumbnail_path = NULL;
|
||||
const char *left_thumbnail_path = NULL;
|
||||
|
||||
if (!xmb)
|
||||
return;
|
||||
|
||||
if (!(string_is_empty(xmb->thumbnail_file_path)))
|
||||
if (menu_thumbnail_get_path(xmb->thumbnail_path_data, MENU_THUMBNAIL_RIGHT, &right_thumbnail_path))
|
||||
{
|
||||
if (filestream_exists(xmb->thumbnail_file_path))
|
||||
task_push_image_load(xmb->thumbnail_file_path,
|
||||
if (filestream_exists(right_thumbnail_path))
|
||||
task_push_image_load(right_thumbnail_path,
|
||||
menu_display_handle_thumbnail_upload, NULL);
|
||||
else
|
||||
video_driver_texture_unload(&xmb->thumbnail);
|
||||
|
||||
free(xmb->thumbnail_file_path);
|
||||
xmb->thumbnail_file_path = NULL;
|
||||
}
|
||||
|
||||
if (!(string_is_empty(xmb->left_thumbnail_file_path)))
|
||||
if (menu_thumbnail_get_path(xmb->thumbnail_path_data, MENU_THUMBNAIL_LEFT, &left_thumbnail_path))
|
||||
{
|
||||
if (filestream_exists(xmb->left_thumbnail_file_path))
|
||||
task_push_image_load(xmb->left_thumbnail_file_path,
|
||||
if (filestream_exists(left_thumbnail_path))
|
||||
task_push_image_load(left_thumbnail_path,
|
||||
menu_display_handle_left_thumbnail_upload, NULL);
|
||||
else
|
||||
video_driver_texture_unload(&xmb->left_thumbnail);
|
||||
|
||||
free(xmb->left_thumbnail_file_path);
|
||||
xmb->left_thumbnail_file_path = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1197,32 +1037,77 @@ static void xmb_set_thumbnail_system(void *data, char*s, size_t len)
|
||||
if (!xmb)
|
||||
return;
|
||||
|
||||
if (!string_is_empty(xmb->thumbnail_system))
|
||||
free(xmb->thumbnail_system);
|
||||
/* There is only one mame thumbnail repo */
|
||||
if (strncmp("MAME", s, 4) == 0)
|
||||
strcpy(s, "MAME");
|
||||
xmb->thumbnail_system = strdup(s);
|
||||
menu_thumbnail_set_system(xmb->thumbnail_path_data, s);
|
||||
}
|
||||
|
||||
static void xmb_reset_thumbnail_content(void *data)
|
||||
static void xmb_unload_thumbnail_textures(void *data)
|
||||
{
|
||||
xmb_handle_t *xmb = (xmb_handle_t*)data;
|
||||
if (!xmb)
|
||||
return;
|
||||
if (!string_is_empty(xmb->thumbnail_content))
|
||||
free(xmb->thumbnail_content);
|
||||
xmb->thumbnail_content = NULL;
|
||||
|
||||
if (xmb->thumbnail)
|
||||
video_driver_texture_unload(&xmb->thumbnail);
|
||||
if (xmb->left_thumbnail)
|
||||
video_driver_texture_unload(&xmb->left_thumbnail);
|
||||
}
|
||||
|
||||
static void xmb_set_thumbnail_content(void *data, char *s, size_t len)
|
||||
{
|
||||
size_t selection = menu_navigation_get_selection();
|
||||
xmb_handle_t *xmb = (xmb_handle_t*)data;
|
||||
if (!xmb)
|
||||
return;
|
||||
if (!string_is_empty(xmb->thumbnail_content))
|
||||
free(xmb->thumbnail_content);
|
||||
xmb->thumbnail_content = strdup(s);
|
||||
|
||||
if (xmb->is_playlist)
|
||||
{
|
||||
/* Playlist content */
|
||||
if (string_is_empty(s))
|
||||
menu_thumbnail_set_content_playlist(xmb->thumbnail_path_data,
|
||||
playlist_get_cached(), selection);
|
||||
}
|
||||
else if (xmb->is_db_manager_list)
|
||||
{
|
||||
/* Database list content */
|
||||
if (string_is_empty(s))
|
||||
{
|
||||
menu_entry_t entry;
|
||||
|
||||
menu_entry_init(&entry);
|
||||
menu_entry_get(&entry, 0, selection, NULL, true);
|
||||
|
||||
if (!string_is_empty(entry.path))
|
||||
menu_thumbnail_set_content(xmb->thumbnail_path_data, entry.path);
|
||||
|
||||
menu_entry_free(&entry);
|
||||
}
|
||||
}
|
||||
else if (string_is_equal(s, "imageviewer"))
|
||||
{
|
||||
/* Filebrowser image updates */
|
||||
menu_entry_t entry;
|
||||
file_list_t *selection_buf = menu_entries_get_selection_buf_ptr(0);
|
||||
xmb_node_t *node = (xmb_node_t*)file_list_get_userdata_at_offset(selection_buf, selection);
|
||||
|
||||
menu_entry_init(&entry);
|
||||
menu_entry_get(&entry, 0, selection, NULL, true);
|
||||
|
||||
if (node)
|
||||
if (!string_is_empty(entry.path) && !string_is_empty(node->fullpath))
|
||||
menu_thumbnail_set_content_image(xmb->thumbnail_path_data, node->fullpath, entry.path);
|
||||
|
||||
menu_entry_free(&entry);
|
||||
}
|
||||
else if (!string_is_empty(s))
|
||||
{
|
||||
/* Annoying leftovers...
|
||||
* This is required to ensure that thumbnails are
|
||||
* updated correctly when navigating deeply through
|
||||
* the sublevels of database manager lists.
|
||||
* Showing thumbnails on database entries is a
|
||||
* pointless nuisance and a waste of CPU cycles, IMHO... */
|
||||
menu_thumbnail_set_content(xmb->thumbnail_path_data, s);
|
||||
}
|
||||
}
|
||||
|
||||
static void xmb_update_savestate_thumbnail_image(void *data)
|
||||
@ -1259,8 +1144,6 @@ static void xmb_selection_pointer_changed(
|
||||
menu_list_t *menu_list = NULL;
|
||||
file_list_t *selection_buf = menu_entries_get_selection_buf_ptr(0);
|
||||
size_t selection = menu_navigation_get_selection();
|
||||
const char *thumb_ident = xmb_thumbnails_ident('R');
|
||||
const char *lft_thumb_ident= xmb_thumbnails_ident('L');
|
||||
|
||||
menu_entries_ctl(MENU_ENTRIES_CTL_LIST_GET, &menu_list);
|
||||
menu_entry_init(&entry);
|
||||
@ -1302,64 +1185,44 @@ static void xmb_selection_pointer_changed(
|
||||
|
||||
ia = xmb->items_active_alpha;
|
||||
iz = xmb->items_active_zoom;
|
||||
if (!string_is_equal(thumb_ident,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)) || !string_is_equal(lft_thumb_ident,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)))
|
||||
if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT) || menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT))
|
||||
{
|
||||
if ((xmb_system_tab > XMB_SYSTEM_TAB_SETTINGS && depth == 1) ||
|
||||
(xmb_system_tab < XMB_SYSTEM_TAB_SETTINGS && depth == 4))
|
||||
bool update_thumbnails = false;
|
||||
|
||||
/* Playlist updates */
|
||||
if (((xmb_system_tab > XMB_SYSTEM_TAB_SETTINGS && depth == 1) ||
|
||||
(xmb_system_tab < XMB_SYSTEM_TAB_SETTINGS && depth == 4)) &&
|
||||
xmb->is_playlist)
|
||||
{
|
||||
if (!string_is_empty(entry.path))
|
||||
xmb_set_thumbnail_content(xmb, entry.path, 0 /* will be ignored */);
|
||||
if (!string_is_equal(thumb_ident,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)))
|
||||
{
|
||||
xmb_update_thumbnail_path(xmb, i, 'R');
|
||||
xmb_update_thumbnail_image(xmb);
|
||||
}
|
||||
if (!string_is_equal(lft_thumb_ident,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)))
|
||||
{
|
||||
xmb_update_thumbnail_path(xmb, i, 'L');
|
||||
xmb_update_thumbnail_image(xmb);
|
||||
}
|
||||
xmb_set_thumbnail_content(xmb, "", 0 /* will be ignored */);
|
||||
update_thumbnails = true;
|
||||
}
|
||||
else if (((entry_type == FILE_TYPE_IMAGE || entry_type == FILE_TYPE_IMAGEVIEWER ||
|
||||
entry_type == FILE_TYPE_RDB || entry_type == FILE_TYPE_RDB_ENTRY)
|
||||
&& xmb_system_tab <= XMB_SYSTEM_TAB_SETTINGS))
|
||||
/* Database list updates
|
||||
* (pointless nuisance...) */
|
||||
else if (depth == 4 && xmb->is_db_manager_list)
|
||||
{
|
||||
if (!string_is_empty(entry.path))
|
||||
xmb_set_thumbnail_content(xmb, entry.path, 0 /* will be ignored */);
|
||||
if (!string_is_equal(thumb_ident,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)))
|
||||
{
|
||||
xmb_update_thumbnail_path(xmb, i, 'R');
|
||||
xmb_update_thumbnail_image(xmb);
|
||||
}
|
||||
else if (!string_is_equal(lft_thumb_ident,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)))
|
||||
{
|
||||
xmb_update_thumbnail_path(xmb, i, 'L');
|
||||
xmb_update_thumbnail_image(xmb);
|
||||
}
|
||||
xmb_set_thumbnail_content(xmb, "", 0 /* will be ignored */);
|
||||
update_thumbnails = true;
|
||||
}
|
||||
else if (filebrowser_get_type() != FILEBROWSER_NONE)
|
||||
/* Filebrowser image updates */
|
||||
else if (entry_type == FILE_TYPE_IMAGEVIEWER || entry_type == FILE_TYPE_IMAGE)
|
||||
{
|
||||
xmb_reset_thumbnail_content(xmb);
|
||||
if (!string_is_equal(thumb_ident,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)))
|
||||
{
|
||||
xmb_update_thumbnail_path(xmb, i, 'R');
|
||||
xmb_update_thumbnail_image(xmb);
|
||||
}
|
||||
else if (!string_is_equal(lft_thumb_ident,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)))
|
||||
{
|
||||
xmb_update_thumbnail_path(xmb, i, 'L');
|
||||
xmb_update_thumbnail_image(xmb);
|
||||
}
|
||||
xmb_set_thumbnail_content(xmb, "imageviewer", 0 /* will be ignored */);
|
||||
update_thumbnails = true;
|
||||
}
|
||||
|
||||
if (update_thumbnails)
|
||||
{
|
||||
if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT))
|
||||
xmb_update_thumbnail_path(xmb, i /* will be ignored */, 'R');
|
||||
|
||||
if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT))
|
||||
xmb_update_thumbnail_path(xmb, i /* will be ignored */, 'L');
|
||||
|
||||
xmb_update_thumbnail_image(xmb);
|
||||
}
|
||||
}
|
||||
|
||||
xmb_update_savestate_thumbnail_path(xmb, i);
|
||||
xmb_update_savestate_thumbnail_image(xmb);
|
||||
}
|
||||
@ -1542,12 +1405,28 @@ static void xmb_list_open_new(xmb_handle_t *xmb,
|
||||
|
||||
if (xmb_system_tab <= XMB_SYSTEM_TAB_SETTINGS)
|
||||
{
|
||||
if (xmb->depth < 4)
|
||||
xmb_reset_thumbnail_content(xmb);
|
||||
xmb_update_thumbnail_path(xmb, 0, 'R');
|
||||
xmb_update_thumbnail_image(xmb);
|
||||
xmb_update_thumbnail_path(xmb, 0, 'L');
|
||||
xmb_update_thumbnail_image(xmb);
|
||||
if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT) || menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT))
|
||||
{
|
||||
/* This code is horrible, full of hacks...
|
||||
* This hack ensures that thumbnails are not cleared
|
||||
* when selecting an entry from a collection via
|
||||
* 'load content'... */
|
||||
if (xmb->depth != 5)
|
||||
xmb_unload_thumbnail_textures(xmb);
|
||||
|
||||
if (xmb->is_playlist || xmb->is_db_manager_list)
|
||||
{
|
||||
xmb_set_thumbnail_content(xmb, "", 0 /* will be ignored */);
|
||||
|
||||
if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT))
|
||||
xmb_update_thumbnail_path(xmb, 0 /* will be ignored */, 'R');
|
||||
|
||||
if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT))
|
||||
xmb_update_thumbnail_path(xmb, 0 /* will be ignored */, 'L');
|
||||
|
||||
xmb_update_thumbnail_image(xmb);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1861,37 +1740,22 @@ static void xmb_list_switch(xmb_handle_t *xmb)
|
||||
xmb_list_switch_new(xmb, selection_buf, dir, selection);
|
||||
xmb->categories_active_idx_old = (unsigned)xmb->categories_selection_ptr;
|
||||
|
||||
if (!string_is_equal(xmb_thumbnails_ident('R'),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)))
|
||||
if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT) || menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT))
|
||||
{
|
||||
menu_entry_t entry;
|
||||
xmb_unload_thumbnail_textures(xmb);
|
||||
|
||||
menu_entry_init(&entry);
|
||||
menu_entry_get(&entry, 0, selection, NULL, true);
|
||||
if (xmb->is_playlist)
|
||||
{
|
||||
xmb_set_thumbnail_content(xmb, "", 0 /* will be ignored */);
|
||||
|
||||
if (!string_is_empty(entry.path))
|
||||
xmb_set_thumbnail_content(xmb, entry.path, 0 /* will be ignored */);
|
||||
if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT))
|
||||
xmb_update_thumbnail_path(xmb, 0 /* will be ignored */, 'R');
|
||||
|
||||
menu_entry_free(&entry);
|
||||
if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT))
|
||||
xmb_update_thumbnail_path(xmb, 0 /* will be ignored */, 'L');
|
||||
|
||||
xmb_update_thumbnail_path(xmb, 0, 'R');
|
||||
xmb_update_thumbnail_image(xmb);
|
||||
}
|
||||
if (!string_is_equal(xmb_thumbnails_ident('L'),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)))
|
||||
{
|
||||
menu_entry_t entry;
|
||||
|
||||
menu_entry_init(&entry);
|
||||
menu_entry_get(&entry, 0, selection, NULL, true);
|
||||
|
||||
if (!string_is_empty(entry.path))
|
||||
xmb_set_thumbnail_content(xmb, entry.path, 0 /* will be ignored */);
|
||||
|
||||
menu_entry_free(&entry);
|
||||
|
||||
xmb_update_thumbnail_path(xmb, 0, 'L');
|
||||
xmb_update_thumbnail_image(xmb);
|
||||
xmb_update_thumbnail_image(xmb);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -2241,27 +2105,29 @@ static void xmb_populate_entries(void *data,
|
||||
const char *label, unsigned k)
|
||||
{
|
||||
xmb_handle_t *xmb = (xmb_handle_t*)data;
|
||||
unsigned xmb_system_tab;
|
||||
|
||||
if (!xmb)
|
||||
return;
|
||||
|
||||
/* Determine whether this is a playlist */
|
||||
xmb_system_tab = xmb_get_system_tab(xmb, (unsigned)xmb->categories_selection_ptr);
|
||||
xmb->is_playlist = (xmb_system_tab == XMB_SYSTEM_TAB_FAVORITES) ||
|
||||
(xmb_system_tab == XMB_SYSTEM_TAB_HISTORY) ||
|
||||
(xmb_system_tab == XMB_SYSTEM_TAB_IMAGES) ||
|
||||
string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_HORIZONTAL_MENU)) ||
|
||||
string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_PLAYLIST_LIST)) ||
|
||||
string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_FAVORITES_LIST)) ||
|
||||
string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_IMAGES_LIST));
|
||||
xmb->is_playlist = xmb->is_playlist && !string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_RDB_ENTRY_DETAIL));
|
||||
|
||||
/* Determine whether this is a database manager list */
|
||||
xmb->is_db_manager_list = string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_DATABASE_MANAGER_LIST));
|
||||
|
||||
if (menu_driver_ctl(RARCH_MENU_CTL_IS_PREVENT_POPULATE, NULL))
|
||||
{
|
||||
xmb_selection_pointer_changed(xmb, false);
|
||||
menu_driver_ctl(RARCH_MENU_CTL_UNSET_PREVENT_POPULATE, NULL);
|
||||
if (!string_is_equal(xmb_thumbnails_ident('R'),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)))
|
||||
{
|
||||
xmb_update_thumbnail_path(xmb, 0, 'R');
|
||||
xmb_update_thumbnail_image(xmb);
|
||||
}
|
||||
xmb_update_savestate_thumbnail_image(xmb);
|
||||
if (!string_is_equal(xmb_thumbnails_ident('L'),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)))
|
||||
{
|
||||
xmb_update_thumbnail_path(xmb, 0, 'L');
|
||||
xmb_update_thumbnail_image(xmb);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@ -2793,8 +2659,6 @@ static int xmb_draw_item(
|
||||
xmb_node_t *core_node,
|
||||
file_list_t *list,
|
||||
float *color,
|
||||
const char *thumb_ident,
|
||||
const char *left_thumb_ident,
|
||||
size_t i,
|
||||
size_t current,
|
||||
unsigned width,
|
||||
@ -2908,13 +2772,9 @@ static int xmb_draw_item(
|
||||
{
|
||||
if (xmb->savestate_thumbnail ||
|
||||
!xmb->use_ps3_layout ||
|
||||
(!string_is_equal
|
||||
(thumb_ident,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))
|
||||
(menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT)
|
||||
&& xmb->thumbnail) ||
|
||||
(!string_is_equal
|
||||
(left_thumb_ident,
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF))
|
||||
(menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT)
|
||||
&& xmb->left_thumbnail
|
||||
&& settings->bools.menu_xmb_vertical_thumbnails)
|
||||
)
|
||||
@ -3075,8 +2935,6 @@ static void xmb_draw_items(
|
||||
menu_display_ctx_rotate_draw_t rotate_draw;
|
||||
xmb_node_t *core_node = NULL;
|
||||
size_t end = 0;
|
||||
const char *thumb_ident = xmb_thumbnails_ident('R');
|
||||
const char *left_thumb_ident= xmb_thumbnails_ident('L');
|
||||
|
||||
if (!list || !list->size || !xmb)
|
||||
return;
|
||||
@ -3126,7 +2984,7 @@ static void xmb_draw_items(
|
||||
&entry,
|
||||
&mymat,
|
||||
xmb, core_node,
|
||||
list, color, thumb_ident, left_thumb_ident,
|
||||
list, color,
|
||||
i, current,
|
||||
width, height);
|
||||
menu_entry_free(&entry);
|
||||
@ -3493,9 +3351,7 @@ static void xmb_frame(void *data, video_frame_info_t *video_info)
|
||||
xmb->icon_spacing_horizontal +
|
||||
pseudo_font_length + min_thumb_size) <= width))
|
||||
{
|
||||
if (xmb->thumbnail
|
||||
&& !string_is_equal(xmb_thumbnails_ident('R'),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)))
|
||||
if (xmb->thumbnail && menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT))
|
||||
{
|
||||
/* Limit thumbnail width */
|
||||
|
||||
@ -3560,9 +3416,7 @@ static void xmb_frame(void *data, video_frame_info_t *video_info)
|
||||
{
|
||||
/* Left Thumbnail in the left margin */
|
||||
|
||||
if (xmb->left_thumbnail
|
||||
&& !string_is_equal(xmb_thumbnails_ident('L'),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)))
|
||||
if (xmb->left_thumbnail && menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT))
|
||||
{
|
||||
/* Limit left thumbnail width */
|
||||
|
||||
@ -3631,9 +3485,7 @@ static void xmb_frame(void *data, video_frame_info_t *video_info)
|
||||
xmb->icon_spacing_horizontal +
|
||||
pseudo_font_length + min_thumb_size) <= width))
|
||||
{
|
||||
if (xmb->left_thumbnail
|
||||
&& !string_is_equal(xmb_thumbnails_ident('L'),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)))
|
||||
if (xmb->left_thumbnail && menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT))
|
||||
{
|
||||
/* Limit left thumbnail width */
|
||||
|
||||
@ -3696,9 +3548,7 @@ static void xmb_frame(void *data, video_frame_info_t *video_info)
|
||||
{
|
||||
/* Left Thumbnail in the left margin */
|
||||
|
||||
if (xmb->left_thumbnail
|
||||
&& !string_is_equal(xmb_thumbnails_ident('L'),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)))
|
||||
if (xmb->left_thumbnail && menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT))
|
||||
{
|
||||
/* Limit left thumbnail width */
|
||||
|
||||
@ -3943,9 +3793,7 @@ static void xmb_frame(void *data, video_frame_info_t *video_info)
|
||||
xmb->icon_spacing_horizontal +
|
||||
pseudo_font_length + min_thumb_size) <= width))
|
||||
{
|
||||
if (xmb->thumbnail &&
|
||||
!string_is_equal(xmb_thumbnails_ident('R'),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)))
|
||||
if (xmb->thumbnail && menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT))
|
||||
{
|
||||
/* Limit right thumbnail width */
|
||||
|
||||
@ -4007,9 +3855,7 @@ static void xmb_frame(void *data, video_frame_info_t *video_info)
|
||||
xmb->icon_spacing_horizontal +
|
||||
pseudo_font_length + min_thumb_size) <= width))
|
||||
{
|
||||
if (xmb->left_thumbnail &&
|
||||
!string_is_equal(xmb_thumbnails_ident('L'),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)))
|
||||
if (xmb->left_thumbnail && menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT))
|
||||
{
|
||||
/* Limit left thumbnail width */
|
||||
|
||||
@ -4520,6 +4366,10 @@ static void *xmb_init(void **userdata, bool video_is_threaded)
|
||||
|
||||
xmb_init_ribbon(xmb);
|
||||
|
||||
xmb->thumbnail_path_data = menu_thumbnail_path_init();
|
||||
if (!xmb->thumbnail_path_data)
|
||||
goto error;
|
||||
|
||||
return menu;
|
||||
|
||||
error:
|
||||
@ -4567,18 +4417,13 @@ static void xmb_free(void *data)
|
||||
|
||||
if (!string_is_empty(xmb->box_message))
|
||||
free(xmb->box_message);
|
||||
if (!string_is_empty(xmb->thumbnail_system))
|
||||
free(xmb->thumbnail_system);
|
||||
if (!string_is_empty(xmb->thumbnail_content))
|
||||
free(xmb->thumbnail_content);
|
||||
if (!string_is_empty(xmb->savestate_thumbnail_file_path))
|
||||
free(xmb->savestate_thumbnail_file_path);
|
||||
if (!string_is_empty(xmb->thumbnail_file_path))
|
||||
free(xmb->thumbnail_file_path);
|
||||
if (!string_is_empty(xmb->left_thumbnail_file_path))
|
||||
free(xmb->left_thumbnail_file_path);
|
||||
if (!string_is_empty(xmb->bg_file_path))
|
||||
free(xmb->bg_file_path);
|
||||
|
||||
if (xmb->thumbnail_path_data)
|
||||
free(xmb->thumbnail_path_data);
|
||||
}
|
||||
|
||||
font_driver_bind_block(NULL, NULL);
|
||||
@ -5087,16 +4932,14 @@ static void xmb_context_reset_internal(xmb_handle_t *xmb,
|
||||
|
||||
xmb_context_reset_horizontal_list(xmb);
|
||||
|
||||
if (!string_is_equal(xmb_thumbnails_ident('R'),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)))
|
||||
if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT) || menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT))
|
||||
{
|
||||
xmb_update_thumbnail_path(xmb, 0, 'R');
|
||||
xmb_update_thumbnail_image(xmb);
|
||||
}
|
||||
if (!string_is_equal(xmb_thumbnails_ident('L'),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF)))
|
||||
{
|
||||
xmb_update_thumbnail_path(xmb, 0, 'L');
|
||||
if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT))
|
||||
xmb_update_thumbnail_path(xmb, 0, 'R');
|
||||
|
||||
if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT))
|
||||
xmb_update_thumbnail_path(xmb, 0, 'L');
|
||||
|
||||
xmb_update_thumbnail_image(xmb);
|
||||
}
|
||||
xmb_update_savestate_thumbnail_image(xmb);
|
||||
@ -5801,8 +5644,8 @@ menu_ctx_driver_t menu_ctx_xmb = {
|
||||
xmb_populate_entries,
|
||||
xmb_toggle,
|
||||
xmb_navigation_clear,
|
||||
xmb_navigation_pointer_changed,
|
||||
xmb_navigation_pointer_changed,
|
||||
NULL, /*xmb_navigation_pointer_changed,*/ /* Note: navigation_set() is called each time navigation_increment/decrement() */
|
||||
NULL, /*xmb_navigation_pointer_changed,*/ /* is called, so linking these just duplicates work... */
|
||||
xmb_navigation_set,
|
||||
xmb_navigation_pointer_changed,
|
||||
xmb_navigation_alphabet,
|
||||
|
@ -1323,8 +1323,24 @@ static int menu_displaylist_parse_playlist(menu_displaylist_info_t *info,
|
||||
strlcpy(label_spacer, PL_LABEL_SPACER_DEFAULT, sizeof(label_spacer));
|
||||
}
|
||||
|
||||
/* Inform menu driver of current system name */
|
||||
if (!string_is_empty(info->path))
|
||||
/* Inform menu driver of current system name
|
||||
* > Note: history, favorites and images_history
|
||||
* require special treatment here, since info->path
|
||||
* is nonsensical in these cases (and we *do* need
|
||||
* to call set_thumbnail_system() in these cases,
|
||||
* since all three playlist types have thumbnail
|
||||
* support) */
|
||||
if (string_is_equal(path_playlist, "history") ||
|
||||
string_is_equal(path_playlist, "favorites") ||
|
||||
string_is_equal(path_playlist, "images_history"))
|
||||
{
|
||||
char system_name[15];
|
||||
system_name[0] = '\0';
|
||||
|
||||
strlcpy(system_name, path_playlist, sizeof(system_name));
|
||||
menu_driver_set_thumbnail_system(system_name, sizeof(system_name));
|
||||
}
|
||||
else if (!string_is_empty(info->path))
|
||||
{
|
||||
char lpl_basename[PATH_MAX_LENGTH];
|
||||
lpl_basename[0] = '\0';
|
||||
@ -1394,24 +1410,6 @@ static int menu_displaylist_parse_playlist(menu_displaylist_info_t *info,
|
||||
}
|
||||
}
|
||||
|
||||
/* If this is a standard collection (not a history list or
|
||||
* favourites), trigger thumbnail update for current selection.
|
||||
* Note: Thumbnail updates must be omitted when using RGUI,
|
||||
* since this functionality is handled elsewhere... */
|
||||
if (i == selection)
|
||||
{
|
||||
if (is_collection && !string_is_empty(label) && !is_rgui)
|
||||
{
|
||||
char *content_basename = strdup(label);
|
||||
/* Note: If menu_driver_set_thumbnail_content() accepted a const pointer,
|
||||
* we could save a string duplication here... */
|
||||
menu_driver_set_thumbnail_content(content_basename, strlen(content_basename) + 1);
|
||||
menu_driver_ctl(RARCH_MENU_CTL_UPDATE_THUMBNAIL_PATH, NULL);
|
||||
menu_driver_ctl(RARCH_MENU_CTL_UPDATE_THUMBNAIL_IMAGE, NULL);
|
||||
free(content_basename);
|
||||
}
|
||||
}
|
||||
|
||||
if (!string_is_empty(path))
|
||||
{
|
||||
/* Standard playlist entry
|
||||
@ -1721,12 +1719,15 @@ static int menu_displaylist_parse_database_entry(menu_handle_t *menu,
|
||||
|
||||
snprintf(crc_str, sizeof(crc_str), "%08X", db_info_entry->crc32);
|
||||
|
||||
/* It is unclear why parsing a database should trigger a
|
||||
* thumbnail update, but I guess this is here for a reason...
|
||||
* Regardless, thumbnail updates must be disabled when using
|
||||
/* This allows thumbnails to be shown while viewing database
|
||||
* entries...
|
||||
* It only makes sense to do this for the first info entry,
|
||||
* since menu drivers cannot handle multiple successive
|
||||
* calls of menu_driver_set_thumbnail_content()...
|
||||
* Note that thumbnail updates must be disabled when using
|
||||
* RGUI, since this functionality is handled elsewhere
|
||||
* (and doing it here creates harmful conflicts) */
|
||||
if (!string_is_equal(settings->arrays.menu_driver, "rgui"))
|
||||
if ((i == 0) && !string_is_equal(settings->arrays.menu_driver, "rgui"))
|
||||
{
|
||||
if (!string_is_empty(db_info_entry->name))
|
||||
strlcpy(thumbnail_content, db_info_entry->name,
|
||||
|
560
menu/menu_thumbnail_path.c
Normal file
560
menu/menu_thumbnail_path.c
Normal file
@ -0,0 +1,560 @@
|
||||
/* Copyright (C) 2010-2019 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (runtime_file.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <string/stdstring.h>
|
||||
#include <file/file_path.h>
|
||||
#include <lists/file_list.h>
|
||||
|
||||
#include "../configuration.h"
|
||||
#include "../msg_hash.h"
|
||||
#include "../paths.h"
|
||||
#include "../file_path_special.h"
|
||||
|
||||
#include "menu_driver.h"
|
||||
#include "widgets/menu_entry.h"
|
||||
|
||||
#include "menu_thumbnail_path.h"
|
||||
|
||||
/* Used fixed size char arrays here, just to avoid
|
||||
* the inconvenience of having to calloc()/free()
|
||||
* each individual entry by hand... */
|
||||
struct menu_thumbnail_path_data
|
||||
{
|
||||
char system[PATH_MAX_LENGTH];
|
||||
char content_path[PATH_MAX_LENGTH];
|
||||
char content_label[PATH_MAX_LENGTH];
|
||||
char content_core_name[PATH_MAX_LENGTH];
|
||||
char content_db_name[PATH_MAX_LENGTH];
|
||||
char content_img[PATH_MAX_LENGTH];
|
||||
char right_path[PATH_MAX_LENGTH];
|
||||
char left_path[PATH_MAX_LENGTH];
|
||||
};
|
||||
|
||||
/* Initialisation */
|
||||
|
||||
/* Creates new thumbnail path data container.
|
||||
* Returns handle to new menu_thumbnail_path_data_t object.
|
||||
* on success, otherwise NULL.
|
||||
* Note: Returned object must be free()d */
|
||||
menu_thumbnail_path_data_t *menu_thumbnail_path_init()
|
||||
{
|
||||
menu_thumbnail_path_data_t *path_data = NULL;
|
||||
path_data = (menu_thumbnail_path_data_t*)calloc(1, sizeof(*path_data));
|
||||
if (!path_data)
|
||||
return NULL;
|
||||
return path_data;
|
||||
}
|
||||
|
||||
/* Resets thumbnail path data
|
||||
* (blanks all internal string containers) */
|
||||
void menu_thumbnail_path_reset(menu_thumbnail_path_data_t *path_data)
|
||||
{
|
||||
if (!path_data)
|
||||
return;
|
||||
|
||||
path_data->system[0] = '\0';
|
||||
path_data->content_path[0] = '\0';
|
||||
path_data->content_label[0] = '\0';
|
||||
path_data->content_core_name[0] = '\0';
|
||||
path_data->content_db_name[0] = '\0';
|
||||
path_data->content_img[0] = '\0';
|
||||
path_data->right_path[0] = '\0';
|
||||
path_data->left_path[0] = '\0';
|
||||
}
|
||||
|
||||
/* Utility Functions */
|
||||
|
||||
/* Returns currently set thumbnail 'type' (Named_Snaps,
|
||||
* Named_Titles, Named_Boxarts) for specified thumbnail
|
||||
* identifier (right, left) */
|
||||
const char *menu_thumbnail_get_type(enum menu_thumbnail_id thumbnail_id)
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
unsigned type = 0;
|
||||
|
||||
if (!settings)
|
||||
return msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF);
|
||||
|
||||
switch (thumbnail_id)
|
||||
{
|
||||
case MENU_THUMBNAIL_RIGHT:
|
||||
type = settings->uints.menu_thumbnails;
|
||||
break;
|
||||
case MENU_THUMBNAIL_LEFT:
|
||||
type = settings->uints.menu_left_thumbnails;
|
||||
break;
|
||||
default:
|
||||
return msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF);
|
||||
}
|
||||
|
||||
switch (type)
|
||||
{
|
||||
case 1:
|
||||
return "Named_Snaps";
|
||||
case 2:
|
||||
return "Named_Titles";
|
||||
case 3:
|
||||
return "Named_Boxarts";
|
||||
case 0:
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return msg_hash_to_str(MENU_ENUM_LABEL_VALUE_OFF);
|
||||
}
|
||||
|
||||
/* Returns true if specified thumbnail is enabled
|
||||
* (i.e. if 'type' is not equal to MENU_ENUM_LABEL_VALUE_OFF) */
|
||||
bool menu_thumbnail_is_enabled(enum menu_thumbnail_id thumbnail_id)
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
|
||||
if (!settings)
|
||||
return false;
|
||||
|
||||
switch (thumbnail_id)
|
||||
{
|
||||
case MENU_THUMBNAIL_RIGHT:
|
||||
return settings->uints.menu_thumbnails != 0;
|
||||
case MENU_THUMBNAIL_LEFT:
|
||||
return settings->uints.menu_left_thumbnails != 0;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Setters */
|
||||
|
||||
/* Fills content_img field of path_data using existing
|
||||
* content_label field (for internal use only) */
|
||||
static void fill_content_img(menu_thumbnail_path_data_t *path_data)
|
||||
{
|
||||
char *scrub_char_pointer = NULL;
|
||||
|
||||
/* Copy source label string */
|
||||
strlcpy(path_data->content_img,
|
||||
path_data->content_label, sizeof(path_data->content_img));
|
||||
|
||||
/* Scrub characters that are not cross-platform and/or violate the
|
||||
* No-Intro filename standard:
|
||||
* http://datomatic.no-intro.org/stuff/The%20Official%20No-Intro%20Convention%20(20071030).zip
|
||||
* Replace these characters in the entry name with underscores */
|
||||
while((scrub_char_pointer = strpbrk(path_data->content_img, "&*/:`\"<>?\\|")))
|
||||
*scrub_char_pointer = '_';
|
||||
|
||||
/* Add PNG extension */
|
||||
strlcat(path_data->content_img,
|
||||
file_path_str(FILE_PATH_PNG_EXTENSION), sizeof(path_data->content_img));
|
||||
}
|
||||
|
||||
/* Sets current 'system' (default database name).
|
||||
* Returns true if 'system' is valid.
|
||||
* > Used as a fallback when individual content lacks an
|
||||
* associated database name */
|
||||
bool menu_thumbnail_set_system(menu_thumbnail_path_data_t *path_data, const char *system)
|
||||
{
|
||||
if (!path_data)
|
||||
return false;
|
||||
|
||||
/* When system is updated, must regenerate right/left
|
||||
* thumbnail paths */
|
||||
path_data->right_path[0] = '\0';
|
||||
path_data->left_path[0] = '\0';
|
||||
|
||||
/* 'Reset' path_data system string */
|
||||
path_data->system[0] = '\0';
|
||||
|
||||
if (string_is_empty(system))
|
||||
return false;
|
||||
|
||||
/* Hack: There is only one MAME thumbnail repo,
|
||||
* so filter any input starting with 'MAME...' */
|
||||
if (strncmp(system, "MAME", 4) == 0)
|
||||
strlcpy(path_data->system, "MAME", sizeof(path_data->system));
|
||||
else
|
||||
strlcpy(path_data->system, system, sizeof(path_data->system));
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Sets current thumbnail content according to the specified label.
|
||||
* Returns true if content is valid */
|
||||
bool menu_thumbnail_set_content(menu_thumbnail_path_data_t *path_data, const char *label)
|
||||
{
|
||||
if (!path_data)
|
||||
return false;
|
||||
|
||||
/* When content is updated, must regenerate right/left
|
||||
* thumbnail paths */
|
||||
path_data->right_path[0] = '\0';
|
||||
path_data->left_path[0] = '\0';
|
||||
|
||||
/* 'Reset' path_data content strings */
|
||||
path_data->content_path[0] = '\0';
|
||||
path_data->content_label[0] = '\0';
|
||||
path_data->content_core_name[0] = '\0';
|
||||
path_data->content_db_name[0] = '\0';
|
||||
path_data->content_img[0] = '\0';
|
||||
|
||||
if (string_is_empty(label))
|
||||
return false;
|
||||
|
||||
/* Cache content label */
|
||||
strlcpy(path_data->content_label, label, sizeof(path_data->content_label));
|
||||
|
||||
/* Determine content image name */
|
||||
fill_content_img(path_data);
|
||||
|
||||
/* Redundant error check... */
|
||||
if (string_is_empty(path_data->content_img))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Sets current thumbnail content to the specified image.
|
||||
* Returns true if content is valid */
|
||||
bool menu_thumbnail_set_content_image(menu_thumbnail_path_data_t *path_data, const char *img_dir, const char *img_name)
|
||||
{
|
||||
if (!path_data)
|
||||
return false;
|
||||
|
||||
/* When content is updated, must regenerate right/left
|
||||
* thumbnail paths */
|
||||
path_data->right_path[0] = '\0';
|
||||
path_data->left_path[0] = '\0';
|
||||
|
||||
/* 'Reset' path_data content strings */
|
||||
path_data->content_path[0] = '\0';
|
||||
path_data->content_label[0] = '\0';
|
||||
path_data->content_core_name[0] = '\0';
|
||||
path_data->content_db_name[0] = '\0';
|
||||
path_data->content_img[0] = '\0';
|
||||
|
||||
if (string_is_empty(img_dir))
|
||||
return false;
|
||||
|
||||
if (string_is_empty(img_name))
|
||||
return false;
|
||||
|
||||
if (path_is_media_type(img_name) != RARCH_CONTENT_IMAGE)
|
||||
return false;
|
||||
|
||||
/* Cache content image name */
|
||||
strlcpy(path_data->content_img,
|
||||
img_name, sizeof(path_data->content_img));
|
||||
|
||||
/* Get image label */
|
||||
strlcpy(path_data->content_label,
|
||||
path_remove_extension(path_data->content_img), sizeof(path_data->content_label));
|
||||
|
||||
/* Set file path */
|
||||
fill_pathname_join(path_data->content_path,
|
||||
img_dir, img_name, sizeof(path_data->content_path));
|
||||
|
||||
/* Set core name to "imageviewer" */
|
||||
strlcpy(path_data->content_core_name,
|
||||
"imageviewer", sizeof(path_data->content_core_name));
|
||||
|
||||
/* Set database name (arbitrarily) to "_images_"
|
||||
* (required for compatibility with menu_thumbnail_update_path(),
|
||||
* but not actually used...) */
|
||||
strlcpy(path_data->content_db_name,
|
||||
"_images_", sizeof(path_data->content_db_name));
|
||||
|
||||
/* Redundant error check */
|
||||
if (string_is_empty(path_data->content_path))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Sets current thumbnail content to the specified playlist entry.
|
||||
* Returns true if content is valid.
|
||||
* > Note: It is always best to use playlists when setting
|
||||
* thumbnail content, since there is no guarantee that the
|
||||
* corresponding menu entry label will contain a useful
|
||||
* identifier (it may be 'tainted', e.g. with the current
|
||||
* core name). 'Real' labels should be extracted from source */
|
||||
bool menu_thumbnail_set_content_playlist(menu_thumbnail_path_data_t *path_data, playlist_t *playlist, size_t idx)
|
||||
{
|
||||
const char *content_path = NULL;
|
||||
const char *content_label = NULL;
|
||||
const char *core_name = NULL;
|
||||
const char *db_name = NULL;
|
||||
|
||||
if (!path_data)
|
||||
return false;
|
||||
|
||||
/* When content is updated, must regenerate right/left
|
||||
* thumbnail paths */
|
||||
path_data->right_path[0] = '\0';
|
||||
path_data->left_path[0] = '\0';
|
||||
|
||||
/* 'Reset' path_data content strings */
|
||||
path_data->content_path[0] = '\0';
|
||||
path_data->content_label[0] = '\0';
|
||||
path_data->content_core_name[0] = '\0';
|
||||
path_data->content_db_name[0] = '\0';
|
||||
path_data->content_img[0] = '\0';
|
||||
|
||||
if (!playlist)
|
||||
return false;
|
||||
|
||||
if (idx >= playlist_get_size(playlist))
|
||||
return false;
|
||||
|
||||
/* Read playlist values */
|
||||
playlist_get_index(playlist, idx,
|
||||
&content_path, &content_label, NULL, &core_name, NULL, &db_name);
|
||||
|
||||
/* Content without a path is invalid by definition */
|
||||
if (string_is_empty(content_path))
|
||||
return false;
|
||||
|
||||
/* Cache content path
|
||||
* (This is required for imageviewer content) */
|
||||
strlcpy(path_data->content_path,
|
||||
content_path, sizeof(path_data->content_path));
|
||||
|
||||
/* Cache core name
|
||||
* (This is required for imageviewer content) */
|
||||
if (!string_is_empty(core_name))
|
||||
strlcpy(path_data->content_core_name,
|
||||
core_name, sizeof(path_data->content_core_name));
|
||||
|
||||
/* Get content label */
|
||||
if (!string_is_empty(content_label))
|
||||
strlcpy(path_data->content_label,
|
||||
content_label, sizeof(path_data->content_label));
|
||||
else
|
||||
fill_short_pathname_representation(path_data->content_label,
|
||||
content_path, sizeof(path_data->content_label));
|
||||
|
||||
/* Determine content image name */
|
||||
fill_content_img(path_data);
|
||||
|
||||
/* Redundant error check... */
|
||||
if (string_is_empty(path_data->content_img))
|
||||
return false;
|
||||
|
||||
/* Thumbnail image name is done -> now check if
|
||||
* per-content database name is defined */
|
||||
if (!string_is_empty(db_name))
|
||||
{
|
||||
/* Hack: There is only one MAME thumbnail repo,
|
||||
* so filter any input starting with 'MAME...' */
|
||||
if (strncmp(db_name, "MAME", 4) == 0)
|
||||
strlcpy(path_data->content_db_name,
|
||||
"MAME", sizeof(path_data->content_db_name));
|
||||
else
|
||||
{
|
||||
char tmp_buf[PATH_MAX_LENGTH];
|
||||
tmp_buf[0] = '\0';
|
||||
|
||||
strlcpy(tmp_buf, db_name, sizeof(tmp_buf));
|
||||
|
||||
/* Remove .lpl extension
|
||||
* > path_remove_extension() requires a char * (not const)
|
||||
* so have to use a temporary buffer... */
|
||||
strlcpy(path_data->content_db_name,
|
||||
path_remove_extension(tmp_buf), sizeof(path_data->content_db_name));
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Updaters */
|
||||
|
||||
/* Updates path for specified thumbnail identifier (right, left).
|
||||
* Must be called after:
|
||||
* - menu_thumbnail_set_system()
|
||||
* - menu_thumbnail_set_content*()
|
||||
* ...and before:
|
||||
* - menu_thumbnail_get_path()
|
||||
* Returns true if generated path is valid */
|
||||
bool menu_thumbnail_update_path(menu_thumbnail_path_data_t *path_data, enum menu_thumbnail_id thumbnail_id)
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
const char *type = menu_thumbnail_get_type(thumbnail_id);
|
||||
const char *system_name = NULL;
|
||||
char *thumbnail_path = NULL;
|
||||
|
||||
if (!path_data)
|
||||
return false;
|
||||
|
||||
/* Determine which path we are updating... */
|
||||
switch (thumbnail_id)
|
||||
{
|
||||
case MENU_THUMBNAIL_RIGHT:
|
||||
thumbnail_path = path_data->right_path;
|
||||
break;
|
||||
case MENU_THUMBNAIL_LEFT:
|
||||
thumbnail_path = path_data->left_path;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
thumbnail_path[0] = '\0';
|
||||
|
||||
/* Sundry error checking */
|
||||
if (!settings)
|
||||
return false;
|
||||
|
||||
if (string_is_empty(settings->paths.directory_thumbnails))
|
||||
return false;
|
||||
|
||||
if (!menu_thumbnail_is_enabled(thumbnail_id))
|
||||
return false;
|
||||
|
||||
/* Generate new path */
|
||||
|
||||
/* > Check path_data for empty strings */
|
||||
if (string_is_empty(path_data->content_img) ||
|
||||
(string_is_empty(path_data->system) &&
|
||||
string_is_empty(path_data->content_db_name)))
|
||||
return false;
|
||||
|
||||
/* > Get current system */
|
||||
system_name = string_is_empty(path_data->content_db_name) ?
|
||||
path_data->system : path_data->content_db_name;
|
||||
|
||||
/* > Special case: thumbnail for imageviewer content
|
||||
* is the image file itself */
|
||||
if (string_is_equal(system_name, "images_history") ||
|
||||
string_is_equal(path_data->content_core_name, "imageviewer"))
|
||||
{
|
||||
if (string_is_empty(path_data->content_path))
|
||||
return false;
|
||||
|
||||
/* imageviewer content is identical for left and right thumbnails */
|
||||
if (path_is_media_type(path_data->content_path) == RARCH_CONTENT_IMAGE)
|
||||
strlcpy(thumbnail_path,
|
||||
path_data->content_path, PATH_MAX_LENGTH * sizeof(char));
|
||||
}
|
||||
else
|
||||
{
|
||||
char tmp_buf[PATH_MAX_LENGTH];
|
||||
tmp_buf[0] = '\0';
|
||||
|
||||
/* > Normal content: assemble path */
|
||||
|
||||
/* >> Base + system name */
|
||||
fill_pathname_join(thumbnail_path, settings->paths.directory_thumbnails,
|
||||
system_name, PATH_MAX_LENGTH * sizeof(char));
|
||||
|
||||
/* >> Add type */
|
||||
fill_pathname_join(tmp_buf, thumbnail_path, type, sizeof(tmp_buf));
|
||||
|
||||
/* >> Add content image */
|
||||
thumbnail_path[0] = '\0';
|
||||
fill_pathname_join(thumbnail_path, tmp_buf,
|
||||
path_data->content_img, PATH_MAX_LENGTH * sizeof(char));
|
||||
}
|
||||
|
||||
/* Final error check - is cached path empty? */
|
||||
if (string_is_empty(thumbnail_path))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Getters */
|
||||
|
||||
/* Fetches the current thumbnail file path of the
|
||||
* specified thumbnail 'type'.
|
||||
* Returns true if path is valid. */
|
||||
bool menu_thumbnail_get_path(menu_thumbnail_path_data_t *path_data, enum menu_thumbnail_id thumbnail_id, const char **path)
|
||||
{
|
||||
char *thumbnail_path = NULL;
|
||||
|
||||
if (!path_data)
|
||||
return false;
|
||||
|
||||
if (!path)
|
||||
return false;
|
||||
|
||||
switch (thumbnail_id)
|
||||
{
|
||||
case MENU_THUMBNAIL_RIGHT:
|
||||
thumbnail_path = path_data->right_path;
|
||||
break;
|
||||
case MENU_THUMBNAIL_LEFT:
|
||||
thumbnail_path = path_data->left_path;
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
|
||||
if (string_is_empty(thumbnail_path))
|
||||
return false;
|
||||
|
||||
*path = thumbnail_path;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Fetches current thumbnail label.
|
||||
* Returns true if label is valid. */
|
||||
bool menu_thumbnail_get_label(menu_thumbnail_path_data_t *path_data, const char **label)
|
||||
{
|
||||
if (!path_data)
|
||||
return false;
|
||||
|
||||
if (!label)
|
||||
return false;
|
||||
|
||||
if (string_is_empty(path_data->content_label))
|
||||
return false;
|
||||
|
||||
*label = path_data->content_label;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Fetches current thumbnail core name.
|
||||
* Returns true if core name is valid. */
|
||||
bool menu_thumbnail_get_core_name(menu_thumbnail_path_data_t *path_data, const char **core_name)
|
||||
{
|
||||
if (!path_data)
|
||||
return false;
|
||||
|
||||
if (!core_name)
|
||||
return false;
|
||||
|
||||
if (string_is_empty(path_data->content_core_name))
|
||||
return false;
|
||||
|
||||
*core_name = path_data->content_core_name;
|
||||
|
||||
return true;
|
||||
}
|
129
menu/menu_thumbnail_path.h
Normal file
129
menu/menu_thumbnail_path.h
Normal file
@ -0,0 +1,129 @@
|
||||
/* Copyright (C) 2010-2019 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (runtime_file.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
* to any person obtaining a copy of this software and associated documentation files (the "Software"),
|
||||
* to deal in the Software without restriction, including without limitation the rights to
|
||||
* use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
|
||||
* and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||
*
|
||||
* The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
|
||||
* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
||||
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef __MENU_THUMBNAIL_PATH_H
|
||||
#define __MENU_THUMBNAIL_PATH_H
|
||||
|
||||
#include <retro_common_api.h>
|
||||
#include <libretro.h>
|
||||
|
||||
#include <boolean.h>
|
||||
|
||||
#include "../playlist.h"
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
/* Note: This implementation reflects the current
|
||||
* setup of:
|
||||
* - menu_driver_set_thumbnail_system()
|
||||
* - menu_driver_set_thumbnail_content()
|
||||
* - menu_driver_update_thumbnail_path()
|
||||
* This is absolutely not the best way to handle things,
|
||||
* but I have no interest in rewriting the existing
|
||||
* menu code... */
|
||||
|
||||
enum menu_thumbnail_id
|
||||
{
|
||||
MENU_THUMBNAIL_RIGHT = 0,
|
||||
MENU_THUMBNAIL_LEFT
|
||||
};
|
||||
|
||||
/* Prevent direct access to menu_thumbnail_path_data_t members */
|
||||
typedef struct menu_thumbnail_path_data menu_thumbnail_path_data_t;
|
||||
|
||||
/* Initialisation */
|
||||
|
||||
/* Creates new thumbnail path data container.
|
||||
* Returns handle to new menu_thumbnail_path_data_t object.
|
||||
* on success, otherwise NULL.
|
||||
* Note: Returned object must be free()d */
|
||||
menu_thumbnail_path_data_t *menu_thumbnail_path_init();
|
||||
|
||||
/* Resets thumbnail path data
|
||||
* (blanks all internal string containers) */
|
||||
void menu_thumbnail_path_reset(menu_thumbnail_path_data_t *path_data);
|
||||
|
||||
/* Utility Functions */
|
||||
|
||||
/* Returns currently set thumbnail 'type' (Named_Snaps,
|
||||
* Named_Titles, Named_Boxarts) for specified thumbnail
|
||||
* identifier (right, left) */
|
||||
const char *menu_thumbnail_get_type(enum menu_thumbnail_id thumbnail_id);
|
||||
|
||||
/* Returns true if specified thumbnail is enabled
|
||||
* (i.e. if 'type' is not equal to MENU_ENUM_LABEL_VALUE_OFF) */
|
||||
bool menu_thumbnail_is_enabled(enum menu_thumbnail_id thumbnail_id);
|
||||
|
||||
/* Setters */
|
||||
|
||||
/* Sets current 'system' (default database name).
|
||||
* Returns true if 'system' is valid.
|
||||
* > Used as a fallback when individual content lacks an
|
||||
* associated database name */
|
||||
bool menu_thumbnail_set_system(menu_thumbnail_path_data_t *path_data, const char *system);
|
||||
|
||||
/* Sets current thumbnail content according to the specified label.
|
||||
* Returns true if content is valid */
|
||||
bool menu_thumbnail_set_content(menu_thumbnail_path_data_t *path_data, const char *label);
|
||||
|
||||
/* Sets current thumbnail content to the specified image.
|
||||
* Returns true if content is valid */
|
||||
bool menu_thumbnail_set_content_image(menu_thumbnail_path_data_t *path_data, const char *img_dir, const char *img_name);
|
||||
|
||||
/* Sets current thumbnail content to the specified playlist entry.
|
||||
* Returns true if content is valid.
|
||||
* > Note: It is always best to use playlists when setting
|
||||
* thumbnail content, since there is no guarantee that the
|
||||
* corresponding menu entry label will contain a useful
|
||||
* identifier (it may be 'tainted', e.g. with the current
|
||||
* core name). 'Real' labels should be extracted from source */
|
||||
bool menu_thumbnail_set_content_playlist(menu_thumbnail_path_data_t *path_data, playlist_t *playlist, size_t idx);
|
||||
|
||||
/* Updaters */
|
||||
|
||||
/* Updates path for specified thumbnail identifier (right, left).
|
||||
* Must be called after:
|
||||
* - menu_thumbnail_set_system()
|
||||
* - menu_thumbnail_set_content*()
|
||||
* ...and before:
|
||||
* - menu_thumbnail_get_path()
|
||||
* Returns true if generated path is valid */
|
||||
bool menu_thumbnail_update_path(menu_thumbnail_path_data_t *path_data, enum menu_thumbnail_id thumbnail_id);
|
||||
|
||||
/* Getters */
|
||||
|
||||
/* Fetches the current thumbnail file path of the
|
||||
* specified thumbnail 'type'.
|
||||
* Returns true if path is valid. */
|
||||
bool menu_thumbnail_get_path(menu_thumbnail_path_data_t *path_data, enum menu_thumbnail_id thumbnail_id, const char **path);
|
||||
|
||||
/* Fetches current thumbnail label.
|
||||
* Returns true if label is valid. */
|
||||
bool menu_thumbnail_get_label(menu_thumbnail_path_data_t *path_data, const char **label);
|
||||
|
||||
/* Fetches current thumbnail core name.
|
||||
* Returns true if core name is valid. */
|
||||
bool menu_thumbnail_get_core_name(menu_thumbnail_path_data_t *path_data, const char **core_name);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
Loading…
x
Reference in New Issue
Block a user