mirror of
https://github.com/libretro/RetroArch.git
synced 2024-11-27 10:10:57 +00:00
(RGUI) Add inline playlist thumbnail support
This commit is contained in:
parent
7c13e57468
commit
c2122ed1d8
@ -384,6 +384,8 @@ static unsigned menu_shader_pipeline = 2;
|
||||
static bool show_advanced_settings = false;
|
||||
|
||||
static unsigned rgui_color_theme = RGUI_THEME_CLASSIC_GREEN;
|
||||
static bool rgui_inline_thumbnails = false;
|
||||
static bool rgui_swap_thumbnails = false;
|
||||
static unsigned rgui_thumbnail_downscaler = RGUI_THUMB_SCALE_POINT;
|
||||
static unsigned rgui_internal_upscale_level = RGUI_UPSCALE_NONE;
|
||||
static bool rgui_full_width_layout = true;
|
||||
|
@ -1509,6 +1509,8 @@ static struct config_bool_setting *populate_settings_bool(settings_t *settings,
|
||||
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("menu_rgui_full_width_layout", &settings->bools.menu_rgui_full_width_layout, true, rgui_full_width_layout, false);
|
||||
SETTING_BOOL("rgui_inline_thumbnails", &settings->bools.menu_rgui_inline_thumbnails, true, rgui_inline_thumbnails, false);
|
||||
SETTING_BOOL("rgui_swap_thumbnails", &settings->bools.menu_rgui_swap_thumbnails, true, rgui_swap_thumbnails, false);
|
||||
#endif
|
||||
#ifdef HAVE_XMB
|
||||
SETTING_BOOL("xmb_shadows_enable", &settings->bools.menu_xmb_shadows_enable, true, xmb_shadows_enable, false);
|
||||
|
@ -172,6 +172,8 @@ typedef struct settings
|
||||
bool menu_rgui_border_filler_thickness_enable;
|
||||
bool menu_rgui_border_filler_enable;
|
||||
bool menu_rgui_full_width_layout;
|
||||
bool menu_rgui_inline_thumbnails;
|
||||
bool menu_rgui_swap_thumbnails;
|
||||
bool menu_xmb_shadows_enable;
|
||||
bool menu_xmb_vertical_thumbnails;
|
||||
bool menu_content_show_settings;
|
||||
|
@ -1133,6 +1133,10 @@ MSG_HASH(MENU_ENUM_LABEL_XMB_VERTICAL_THUMBNAILS,
|
||||
"xmb_vertical_thumbnails")
|
||||
MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER,
|
||||
"rgui_thumbnail_downscaler")
|
||||
MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_INLINE_THUMBNAILS,
|
||||
"rgui_inline_thumbnails")
|
||||
MSG_HASH(MENU_ENUM_LABEL_MENU_RGUI_SWAP_THUMBNAILS,
|
||||
"rgui_swap_thumbnails")
|
||||
MSG_HASH(MENU_ENUM_LABEL_THUMBNAILS_DIRECTORY,
|
||||
"thumbnails_directory")
|
||||
MSG_HASH(MENU_ENUM_LABEL_THUMBNAILS_UPDATER_LIST,
|
||||
|
@ -2970,10 +2970,18 @@ MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_THUMBNAILS,
|
||||
"Thumbnails"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_THUMBNAILS_RGUI,
|
||||
"Top Thumbnail"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_LEFT_THUMBNAILS,
|
||||
"Left Thumbnails"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_LEFT_THUMBNAILS_RGUI,
|
||||
"Bottom Thumbnail"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_LEFT_THUMBNAILS_OZONE,
|
||||
"Second Thumbnail"
|
||||
@ -2982,13 +2990,29 @@ MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_XMB_VERTICAL_THUMBNAILS,
|
||||
"Thumbnails Vertical Disposition"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_MENU_RGUI_INLINE_THUMBNAILS,
|
||||
"Show Playlist Thumbnails"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_MENU_RGUI_INLINE_THUMBNAILS,
|
||||
"Enable display of inline downscaled thumbnails while viewing playlists. When disabled, 'Top Thumbnail' may still be toggled fullscreen by pressing RetroPad Y."
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_MENU_RGUI_SWAP_THUMBNAILS,
|
||||
"Swap Thumbnails"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_MENU_RGUI_SWAP_THUMBNAILS,
|
||||
"Swaps the display positions of 'Top Thumbnail' and 'Bottom Thumbnail'."
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_MENU_RGUI_THUMBNAIL_DOWNSCALER,
|
||||
"Thumbnail Downscaling Method"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER,
|
||||
"Resampling method used when shrinking large thumbnails to fit the screen."
|
||||
"Resampling method used when shrinking large thumbnails to fit the display."
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_RGUI_THUMB_SCALE_POINT,
|
||||
@ -5751,10 +5775,18 @@ MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_THUMBNAILS,
|
||||
"Type of thumbnail to display."
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_THUMBNAILS_RGUI,
|
||||
"Type of thumbnail to display at the top right of playlists. This thumbnail may be toggled fullscreen by pressing RetroPad Y."
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_LEFT_THUMBNAILS,
|
||||
"Type of thumbnail to display at the left."
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_LEFT_THUMBNAILS_RGUI,
|
||||
"Type of thumbnail to display at the bottom right of playlists."
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_LEFT_THUMBNAILS_OZONE,
|
||||
"Replace the content metadata panel by another thumbnail."
|
||||
|
@ -111,11 +111,17 @@ int action_switch_thumbnail(const char *path,
|
||||
|
||||
if (settings->uints.menu_thumbnails == 0)
|
||||
{
|
||||
settings->uints.menu_left_thumbnails++;
|
||||
if (settings->uints.menu_left_thumbnails > 3)
|
||||
settings->uints.menu_left_thumbnails = 1;
|
||||
menu_driver_ctl(RARCH_MENU_CTL_UPDATE_THUMBNAIL_PATH, NULL);
|
||||
menu_driver_ctl(RARCH_MENU_CTL_UPDATE_THUMBNAIL_IMAGE, NULL);
|
||||
/* RGUI is a special case where thumbnail 'switch' corresponds to
|
||||
* toggling thumbnail view on/off. For other menu drivers, we
|
||||
* cycle through available thumbnail types. */
|
||||
if(!string_is_equal(settings->arrays.menu_driver, "rgui"))
|
||||
{
|
||||
settings->uints.menu_left_thumbnails++;
|
||||
if (settings->uints.menu_left_thumbnails > 3)
|
||||
settings->uints.menu_left_thumbnails = 1;
|
||||
menu_driver_ctl(RARCH_MENU_CTL_UPDATE_THUMBNAIL_PATH, NULL);
|
||||
menu_driver_ctl(RARCH_MENU_CTL_UPDATE_THUMBNAIL_IMAGE, NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -312,7 +312,9 @@ default_sublabel_macro(action_bind_sublabel_stdin_cmd_enable, MENU_
|
||||
default_sublabel_macro(action_bind_sublabel_mouse_enable, MENU_ENUM_SUBLABEL_MOUSE_ENABLE)
|
||||
default_sublabel_macro(action_bind_sublabel_pointer_enable, MENU_ENUM_SUBLABEL_POINTER_ENABLE)
|
||||
default_sublabel_macro(action_bind_sublabel_thumbnails, MENU_ENUM_SUBLABEL_THUMBNAILS)
|
||||
default_sublabel_macro(action_bind_sublabel_thumbnails_rgui, MENU_ENUM_SUBLABEL_THUMBNAILS_RGUI)
|
||||
default_sublabel_macro(action_bind_sublabel_left_thumbnails, MENU_ENUM_SUBLABEL_LEFT_THUMBNAILS)
|
||||
default_sublabel_macro(action_bind_sublabel_left_thumbnails_rgui, MENU_ENUM_SUBLABEL_LEFT_THUMBNAILS_RGUI)
|
||||
default_sublabel_macro(action_bind_sublabel_left_thumbnails_ozone, MENU_ENUM_SUBLABEL_LEFT_THUMBNAILS_OZONE)
|
||||
default_sublabel_macro(action_bind_sublabel_timedate_enable, MENU_ENUM_SUBLABEL_TIMEDATE_ENABLE)
|
||||
default_sublabel_macro(action_bind_sublabel_timedate_style, MENU_ENUM_SUBLABEL_TIMEDATE_STYLE)
|
||||
@ -526,6 +528,8 @@ default_sublabel_macro(action_bind_sublabel_menu_linear_filter,
|
||||
default_sublabel_macro(action_bind_sublabel_menu_rgui_aspect_ratio_lock, MENU_ENUM_SUBLABEL_MENU_RGUI_ASPECT_RATIO_LOCK)
|
||||
default_sublabel_macro(action_bind_sublabel_rgui_menu_color_theme, MENU_ENUM_SUBLABEL_RGUI_MENU_COLOR_THEME)
|
||||
default_sublabel_macro(action_bind_sublabel_rgui_menu_theme_preset, MENU_ENUM_SUBLABEL_RGUI_MENU_THEME_PRESET)
|
||||
default_sublabel_macro(action_bind_sublabel_menu_rgui_inline_thumbnails, MENU_ENUM_SUBLABEL_MENU_RGUI_INLINE_THUMBNAILS)
|
||||
default_sublabel_macro(action_bind_sublabel_menu_rgui_swap_thumbnails, MENU_ENUM_SUBLABEL_MENU_RGUI_SWAP_THUMBNAILS)
|
||||
default_sublabel_macro(action_bind_sublabel_menu_rgui_thumbnail_downscaler, MENU_ENUM_SUBLABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER)
|
||||
default_sublabel_macro(action_bind_sublabel_content_runtime_log, MENU_ENUM_SUBLABEL_CONTENT_RUNTIME_LOG)
|
||||
default_sublabel_macro(action_bind_sublabel_content_runtime_log_aggregate, MENU_ENUM_SUBLABEL_CONTENT_RUNTIME_LOG_AGGREGATE)
|
||||
@ -1599,11 +1603,23 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_timedate_style);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_THUMBNAILS:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_thumbnails);
|
||||
settings = config_get_ptr();
|
||||
if (string_is_equal(settings->arrays.menu_driver, "rgui"))
|
||||
{
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_thumbnails_rgui);
|
||||
}
|
||||
else
|
||||
{
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_thumbnails);
|
||||
}
|
||||
break;
|
||||
case MENU_ENUM_LABEL_LEFT_THUMBNAILS:
|
||||
settings = config_get_ptr();
|
||||
if (string_is_equal(settings->arrays.menu_driver, "ozone"))
|
||||
if (string_is_equal(settings->arrays.menu_driver, "rgui"))
|
||||
{
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_left_thumbnails_rgui);
|
||||
}
|
||||
else if (string_is_equal(settings->arrays.menu_driver, "ozone"))
|
||||
{
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_left_thumbnails_ozone);
|
||||
}
|
||||
@ -2408,6 +2424,12 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
|
||||
case MENU_ENUM_LABEL_RGUI_MENU_THEME_PRESET:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_rgui_menu_theme_preset);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_MENU_RGUI_INLINE_THUMBNAILS:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_rgui_inline_thumbnails);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_MENU_RGUI_SWAP_THUMBNAILS:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_rgui_swap_thumbnails);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_menu_rgui_thumbnail_downscaler);
|
||||
break;
|
||||
|
@ -448,9 +448,11 @@ typedef struct
|
||||
rgui_colors_t colors;
|
||||
bool is_playlist;
|
||||
bool entry_has_thumbnail;
|
||||
bool show_thumbnail;
|
||||
bool entry_has_left_thumbnail;
|
||||
bool show_fs_thumbnail;
|
||||
menu_thumbnail_path_data_t *thumbnail_path_data;
|
||||
uint32_t thumbnail_queue_size;
|
||||
uint32_t left_thumbnail_queue_size;
|
||||
bool show_wallpaper;
|
||||
char theme_preset_path[PATH_MAX_LENGTH]; /* Must be a fixed length array... */
|
||||
char menu_title[255]; /* Must be a fixed length array... */
|
||||
@ -463,8 +465,13 @@ typedef struct
|
||||
struct scaler_ctx image_scaler;
|
||||
} rgui_t;
|
||||
|
||||
static unsigned mini_thumbnail_max_width = 0;
|
||||
static unsigned mini_thumbnail_max_height = 0;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
unsigned max_width;
|
||||
unsigned max_height;
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
bool is_valid;
|
||||
@ -472,7 +479,29 @@ typedef struct
|
||||
uint16_t *data;
|
||||
} thumbnail_t;
|
||||
|
||||
static thumbnail_t thumbnail = {
|
||||
static thumbnail_t fs_thumbnail = {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
false,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
static thumbnail_t mini_thumbnail = {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
false,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
||||
|
||||
static thumbnail_t mini_left_thumbnail = {
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
false,
|
||||
@ -678,33 +707,34 @@ static void process_wallpaper(rgui_t *rgui, struct texture_image *image)
|
||||
rgui->force_redraw = true;
|
||||
}
|
||||
|
||||
static bool request_thumbnail(rgui_t *rgui, const char *path)
|
||||
static bool request_thumbnail(thumbnail_t *thumbnail, enum menu_thumbnail_id thumbnail_id, uint32_t *queue_size, 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_empty(path) && !string_is_empty(thumbnail->path))
|
||||
{
|
||||
if (string_is_equal(thumbnail.path, path))
|
||||
if (string_is_equal(thumbnail->path, path))
|
||||
return true;
|
||||
}
|
||||
|
||||
/* 'Reset' current thumbnail */
|
||||
thumbnail.width = 0;
|
||||
thumbnail.height = 0;
|
||||
thumbnail.is_valid = false;
|
||||
free(thumbnail.path);
|
||||
thumbnail.path = NULL;
|
||||
thumbnail->width = 0;
|
||||
thumbnail->height = 0;
|
||||
thumbnail->is_valid = false;
|
||||
free(thumbnail->path);
|
||||
thumbnail->path = NULL;
|
||||
|
||||
/* Ensure that new path is valid... */
|
||||
if (!string_is_empty(path))
|
||||
{
|
||||
thumbnail.path = strdup(path);
|
||||
thumbnail->path = strdup(path);
|
||||
if (filestream_exists(path))
|
||||
{
|
||||
/* Would like to cancel any existing image load tasks
|
||||
* here, but can't see how to do it... */
|
||||
if(task_push_image_load(thumbnail.path, menu_display_handle_thumbnail_upload, NULL))
|
||||
if(task_push_image_load(thumbnail->path, (thumbnail_id == MENU_THUMBNAIL_LEFT) ?
|
||||
menu_display_handle_left_thumbnail_upload : menu_display_handle_thumbnail_upload, NULL))
|
||||
{
|
||||
rgui->thumbnail_queue_size++;
|
||||
*queue_size = *queue_size + 1;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -713,28 +743,29 @@ static bool request_thumbnail(rgui_t *rgui, const char *path)
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool downscale_thumbnail(rgui_t *rgui, struct texture_image *image_src, struct texture_image *image_dst)
|
||||
static bool downscale_thumbnail(rgui_t *rgui, unsigned max_width, unsigned max_height,
|
||||
struct texture_image *image_src, struct texture_image *image_dst)
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
|
||||
/* Determine output dimensions */
|
||||
float display_aspect_ratio = (float)rgui_frame_buf.width / (float)rgui_frame_buf.height;
|
||||
float display_aspect_ratio = (float)max_width / (float)max_height;
|
||||
float aspect_ratio = (float)image_src->width / (float)image_src->height;
|
||||
if (aspect_ratio > display_aspect_ratio)
|
||||
{
|
||||
image_dst->width = rgui_frame_buf.width;
|
||||
image_dst->height = image_src->height * rgui_frame_buf.width / image_src->width;
|
||||
image_dst->width = max_width;
|
||||
image_dst->height = image_src->height * max_width / image_src->width;
|
||||
/* Account for any possible rounding errors... */
|
||||
image_dst->height = (image_dst->height < 1) ? 1 : image_dst->height;
|
||||
image_dst->height = (image_dst->height > rgui_frame_buf.height) ? rgui_frame_buf.height : image_dst->height;
|
||||
image_dst->height = (image_dst->height > max_height) ? max_height : image_dst->height;
|
||||
}
|
||||
else
|
||||
{
|
||||
image_dst->height = rgui_frame_buf.height;
|
||||
image_dst->width = image_src->width * rgui_frame_buf.height / image_src->height;
|
||||
image_dst->height = max_height;
|
||||
image_dst->width = image_src->width * max_height / image_src->height;
|
||||
/* Account for any possible rounding errors... */
|
||||
image_dst->width = (image_dst->width < 1) ? 1 : image_dst->width;
|
||||
image_dst->width = (image_dst->width > rgui_frame_buf.width) ? rgui_frame_buf.width : image_dst->width;
|
||||
image_dst->width = (image_dst->width > max_width) ? max_width : image_dst->width;
|
||||
}
|
||||
|
||||
/* Allocate pixel buffer */
|
||||
@ -805,7 +836,7 @@ static bool downscale_thumbnail(rgui_t *rgui, struct texture_image *image_src, s
|
||||
return true;
|
||||
}
|
||||
|
||||
static void process_thumbnail(rgui_t *rgui, struct texture_image *image_src)
|
||||
static void process_thumbnail(rgui_t *rgui, thumbnail_t *thumbnail, uint32_t *queue_size, struct texture_image *image_src)
|
||||
{
|
||||
unsigned x, y;
|
||||
struct texture_image *image = NULL;
|
||||
@ -818,25 +849,20 @@ static void process_thumbnail(rgui_t *rgui, struct texture_image *image_src)
|
||||
|
||||
/* Ensure that we only process the most recently loaded
|
||||
* thumbnail image (i.e. don't waste CPU cycles processing
|
||||
* old images if we have a backlog)
|
||||
* > NB: After some testing, cannot seem to ever trigger a
|
||||
* situation where rgui->thumbnail_queue_size is greater
|
||||
* than 1, so perhaps image loading is synchronous after all.
|
||||
* This probably makes the check redundant, but we'll leave
|
||||
* it here for now... */
|
||||
if (rgui->thumbnail_queue_size > 0)
|
||||
rgui->thumbnail_queue_size--;
|
||||
if (rgui->thumbnail_queue_size > 0)
|
||||
* old images if we have a backlog) */
|
||||
if (*queue_size > 0)
|
||||
*queue_size = *queue_size - 1;
|
||||
if (*queue_size > 0)
|
||||
return;
|
||||
|
||||
/* Sanity check */
|
||||
if (!image_src->pixels || (image_src->width < 1) || (image_src->height < 1) || !thumbnail.data)
|
||||
if (!image_src->pixels || (image_src->width < 1) || (image_src->height < 1) || !thumbnail->data)
|
||||
return;
|
||||
|
||||
/* Downscale thumbnail if it exceeds maximum size limits */
|
||||
if ((image_src->width > rgui_frame_buf.width) || (image_src->height > rgui_frame_buf.height))
|
||||
if ((image_src->width > thumbnail->max_width) || (image_src->height > thumbnail->max_height))
|
||||
{
|
||||
if (!downscale_thumbnail(rgui, image_src, &image_resampled))
|
||||
if (!downscale_thumbnail(rgui, thumbnail->max_width, thumbnail->max_height, image_src, &image_resampled))
|
||||
return;
|
||||
image = &image_resampled;
|
||||
}
|
||||
@ -845,20 +871,20 @@ static void process_thumbnail(rgui_t *rgui, struct texture_image *image_src)
|
||||
image = image_src;
|
||||
}
|
||||
|
||||
thumbnail.width = image->width;
|
||||
thumbnail.height = image->height;
|
||||
thumbnail->width = image->width;
|
||||
thumbnail->height = image->height;
|
||||
|
||||
/* Copy image to thumbnail buffer, performing pixel format conversion */
|
||||
for (x = 0; x < thumbnail.width; x++)
|
||||
for (x = 0; x < thumbnail->width; x++)
|
||||
{
|
||||
for (y = 0; y < thumbnail.height; y++)
|
||||
for (y = 0; y < thumbnail->height; y++)
|
||||
{
|
||||
thumbnail.data[x + (y * thumbnail.width)] =
|
||||
argb32_to_pixel_platform_format(image->pixels[x + (y * thumbnail.width)]);
|
||||
thumbnail->data[x + (y * thumbnail->width)] =
|
||||
argb32_to_pixel_platform_format(image->pixels[x + (y * thumbnail->width)]);
|
||||
}
|
||||
}
|
||||
|
||||
thumbnail.is_valid = true;
|
||||
thumbnail->is_valid = true;
|
||||
|
||||
/* Tell menu that a display update is required */
|
||||
rgui->force_redraw = true;
|
||||
@ -872,9 +898,10 @@ static void process_thumbnail(rgui_t *rgui, struct texture_image *image_src)
|
||||
|
||||
static bool rgui_load_image(void *userdata, void *data, enum menu_image_type type)
|
||||
{
|
||||
rgui_t *rgui = (rgui_t*)userdata;
|
||||
rgui_t *rgui = (rgui_t*)userdata;
|
||||
settings_t *settings = config_get_ptr();
|
||||
|
||||
if (!rgui || !data)
|
||||
if (!rgui || !data || !settings)
|
||||
return false;
|
||||
|
||||
switch (type)
|
||||
@ -888,7 +915,27 @@ static bool rgui_load_image(void *userdata, void *data, enum menu_image_type typ
|
||||
case MENU_IMAGE_THUMBNAIL:
|
||||
{
|
||||
struct texture_image *image = (struct texture_image*)data;
|
||||
process_thumbnail(rgui, image);
|
||||
|
||||
if (rgui->show_fs_thumbnail)
|
||||
process_thumbnail(rgui, &fs_thumbnail, &rgui->thumbnail_queue_size, image);
|
||||
else if (settings->bools.menu_rgui_inline_thumbnails)
|
||||
process_thumbnail(rgui, &mini_thumbnail, &rgui->thumbnail_queue_size, image);
|
||||
else
|
||||
{
|
||||
/* If user toggles settings rapidly on very slow systems,
|
||||
* it is possible for a thumbnail to be requested without
|
||||
* it ever being processed. In this case, we still have to
|
||||
* decrement the thumbnail queue (otherwise image updates
|
||||
* will get 'stuck') */
|
||||
if (rgui->thumbnail_queue_size > 0)
|
||||
rgui->thumbnail_queue_size--;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MENU_IMAGE_LEFT_THUMBNAIL:
|
||||
{
|
||||
struct texture_image *image = (struct texture_image*)data;
|
||||
process_thumbnail(rgui, &mini_left_thumbnail, &rgui->left_thumbnail_queue_size, image);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@ -920,7 +967,7 @@ static bool rgui_render_wallpaper(void)
|
||||
return false;
|
||||
}
|
||||
|
||||
static void rgui_render_thumbnail(void)
|
||||
static void rgui_render_fs_thumbnail(void)
|
||||
{
|
||||
size_t fb_pitch;
|
||||
unsigned fb_width, fb_height;
|
||||
@ -929,7 +976,7 @@ static void rgui_render_thumbnail(void)
|
||||
unsigned thumb_x_offset, thumb_y_offset;
|
||||
unsigned width, height;
|
||||
|
||||
if (thumbnail.is_valid && rgui_frame_buf.data && thumbnail.data)
|
||||
if (fs_thumbnail.is_valid && rgui_frame_buf.data && fs_thumbnail.data)
|
||||
{
|
||||
menu_display_get_fb_size(&fb_width, &fb_height, &fb_pitch);
|
||||
|
||||
@ -938,27 +985,27 @@ static void rgui_render_thumbnail(void)
|
||||
* cannot assume fb_width and fb_height are constant and
|
||||
* >= thumbnail.width and thumbnail.height (even though
|
||||
* they are...) */
|
||||
if (thumbnail.width <= fb_width)
|
||||
if (fs_thumbnail.width <= fb_width)
|
||||
{
|
||||
thumb_x_offset = 0;
|
||||
fb_x_offset = (fb_width - thumbnail.width) >> 1;
|
||||
width = thumbnail.width;
|
||||
fb_x_offset = (fb_width - fs_thumbnail.width) >> 1;
|
||||
width = fs_thumbnail.width;
|
||||
}
|
||||
else
|
||||
{
|
||||
thumb_x_offset = (thumbnail.width - fb_width) >> 1;
|
||||
thumb_x_offset = (fs_thumbnail.width - fb_width) >> 1;
|
||||
fb_x_offset = 0;
|
||||
width = fb_width;
|
||||
}
|
||||
if (thumbnail.height <= fb_height)
|
||||
if (fs_thumbnail.height <= fb_height)
|
||||
{
|
||||
thumb_y_offset = 0;
|
||||
fb_y_offset = (fb_height - thumbnail.height) >> 1;
|
||||
height = thumbnail.height;
|
||||
fb_y_offset = (fb_height - fs_thumbnail.height) >> 1;
|
||||
height = fs_thumbnail.height;
|
||||
}
|
||||
else
|
||||
{
|
||||
thumb_y_offset = (thumbnail.height - fb_height) >> 1;
|
||||
thumb_y_offset = (fs_thumbnail.height - fb_height) >> 1;
|
||||
fb_y_offset = 0;
|
||||
height = fb_height;
|
||||
}
|
||||
@ -969,7 +1016,65 @@ static void rgui_render_thumbnail(void)
|
||||
for (x = 0; x < width; x++)
|
||||
{
|
||||
rgui_frame_buf.data[(y + fb_y_offset) * (fb_pitch >> 1) + (x + fb_x_offset)] =
|
||||
thumbnail.data[(x + thumb_x_offset) + ((y + thumb_y_offset) * thumbnail.width)];
|
||||
fs_thumbnail.data[(x + thumb_x_offset) + ((y + thumb_y_offset) * fs_thumbnail.width)];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static unsigned inline rgui_get_mini_thumbnail_fullwidth(void)
|
||||
{
|
||||
unsigned width = mini_thumbnail.is_valid ? mini_thumbnail.width : 0;
|
||||
unsigned left_width = mini_left_thumbnail.is_valid ? mini_left_thumbnail.width : 0;
|
||||
return width >= left_width ? width : left_width;
|
||||
}
|
||||
|
||||
static void rgui_render_mini_thumbnail(thumbnail_t *thumbnail, enum menu_thumbnail_id thumbnail_id)
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
size_t fb_pitch;
|
||||
unsigned fb_width, fb_height;
|
||||
unsigned term_width, term_height;
|
||||
unsigned x, y;
|
||||
unsigned fb_x_offset, fb_y_offset;
|
||||
unsigned thumbnail_fullwidth = rgui_get_mini_thumbnail_fullwidth();
|
||||
|
||||
if (!thumbnail || !settings)
|
||||
return;
|
||||
|
||||
if (thumbnail->is_valid && rgui_frame_buf.data && thumbnail->data)
|
||||
{
|
||||
menu_display_get_fb_size(&fb_width, &fb_height, &fb_pitch);
|
||||
|
||||
term_width = RGUI_TERM_WIDTH(fb_width) * FONT_WIDTH_STRIDE;
|
||||
term_height = RGUI_TERM_HEIGHT(fb_height) * FONT_HEIGHT_STRIDE;
|
||||
|
||||
/* Sanity check (this can never, ever happen, so just return
|
||||
* instead of trying to crop the thumbnail image...) */
|
||||
if ((thumbnail_fullwidth > term_width) || (thumbnail->height > term_height))
|
||||
return;
|
||||
|
||||
fb_x_offset = (RGUI_TERM_START_X(fb_width) + term_width) -
|
||||
(thumbnail->width + ((thumbnail_fullwidth - thumbnail->width) >> 1));
|
||||
|
||||
if (((thumbnail_id == MENU_THUMBNAIL_RIGHT) && !settings->bools.menu_rgui_swap_thumbnails) ||
|
||||
((thumbnail_id == MENU_THUMBNAIL_LEFT) && settings->bools.menu_rgui_swap_thumbnails))
|
||||
{
|
||||
fb_y_offset = RGUI_TERM_START_Y(fb_height) + ((thumbnail->max_height - thumbnail->height) >> 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
fb_y_offset = (RGUI_TERM_START_Y(fb_height) + term_height) -
|
||||
(thumbnail->height + ((thumbnail->max_height - thumbnail->height) >> 1));
|
||||
}
|
||||
|
||||
/* Copy thumbnail to framebuffer */
|
||||
for (y = 0; y < thumbnail->height; y++)
|
||||
{
|
||||
for (x = 0; x < thumbnail->width; x++)
|
||||
{
|
||||
rgui_frame_buf.data[(y + fb_y_offset) * (fb_pitch >> 1) + (x + fb_x_offset)] =
|
||||
thumbnail->data[x + (y * thumbnail->width)];
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1359,8 +1464,8 @@ static void rgui_render_background(rgui_t *rgui)
|
||||
dst += pitch_in_pixels * 4;
|
||||
}
|
||||
|
||||
/* Skip drawing border if we are currently showing a thumbnail */
|
||||
if (!(rgui->show_thumbnail && rgui->entry_has_thumbnail && (thumbnail.is_valid || (rgui->thumbnail_queue_size > 0))))
|
||||
/* Skip drawing border if we are currently showing a fullscreen thumbnail */
|
||||
if (!(rgui->show_fs_thumbnail && rgui->entry_has_thumbnail && (fs_thumbnail.is_valid || (rgui->thumbnail_queue_size > 0))))
|
||||
{
|
||||
if (rgui_frame_buf.data)
|
||||
{
|
||||
@ -1489,7 +1594,7 @@ static void rgui_render(void *data, bool is_idle)
|
||||
menu_animation_ctx_ticker_t ticker;
|
||||
static const char* const ticker_spacer = RGUI_TICKER_SPACER;
|
||||
unsigned x, y;
|
||||
size_t i, end, fb_pitch, old_start;
|
||||
size_t i, end, fb_pitch, old_start, new_start;
|
||||
unsigned fb_width, fb_height;
|
||||
int bottom;
|
||||
size_t entries_end = 0;
|
||||
@ -1622,14 +1727,14 @@ static void rgui_render(void *data, bool is_idle)
|
||||
ticker.type_enum = (enum menu_animation_ticker_type)settings->uints.menu_ticker_type;
|
||||
ticker.spacer = ticker_spacer;
|
||||
|
||||
/* If thumbnails are enabled and we are viewing a playlist,
|
||||
* switch to thumbnail view mode if either current thumbnail
|
||||
/* If fullscreen thumbnails are enabled and we are viewing a playlist,
|
||||
* switch to fullscreen thumbnail view mode if either current thumbnail
|
||||
* is valid or we are waiting for current thumbnail to load
|
||||
* (if load is pending we'll get a blank screen + title, but
|
||||
* 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->entry_has_thumbnail && (thumbnail.is_valid || (rgui->thumbnail_queue_size > 0)))
|
||||
if (rgui->show_fs_thumbnail && rgui->entry_has_thumbnail && (fs_thumbnail.is_valid || (rgui->thumbnail_queue_size > 0)))
|
||||
{
|
||||
const char *thumbnail_title = NULL;
|
||||
char thumbnail_title_buf[255];
|
||||
@ -1637,7 +1742,7 @@ static void rgui_render(void *data, bool is_idle)
|
||||
thumbnail_title_buf[0] = '\0';
|
||||
|
||||
/* Draw thumbnail */
|
||||
rgui_render_thumbnail();
|
||||
rgui_render_fs_thumbnail();
|
||||
|
||||
/* Get thumbnail title */
|
||||
if (menu_thumbnail_get_label(rgui->thumbnail_path_data, &thumbnail_title))
|
||||
@ -1665,11 +1770,40 @@ static void rgui_render(void *data, bool is_idle)
|
||||
}
|
||||
else
|
||||
{
|
||||
/* No thumbnail - render usual text */
|
||||
/* Render usual text */
|
||||
char title_buf[255];
|
||||
unsigned timedate_x = (RGUI_TERM_START_X(fb_width) + (RGUI_TERM_WIDTH(fb_width) * FONT_WIDTH_STRIDE)) -
|
||||
(5 * FONT_WIDTH_STRIDE);
|
||||
unsigned core_name_len = ((timedate_x - RGUI_TERM_START_X(fb_width)) / FONT_WIDTH_STRIDE) - 3;
|
||||
bool show_mini_thumbnails = rgui->is_playlist && settings->bools.menu_rgui_inline_thumbnails;
|
||||
bool show_thumbnail = false;
|
||||
bool show_left_thumbnail = false;
|
||||
unsigned thumbnail_panel_width = 0;
|
||||
unsigned term_mid_point = 0;
|
||||
|
||||
/* Cache mini thumbnail related parameters, if required */
|
||||
if (show_mini_thumbnails)
|
||||
{
|
||||
/* Get whether each thumbnail type is enabled */
|
||||
show_thumbnail = rgui->entry_has_thumbnail &&
|
||||
(mini_thumbnail.is_valid || (rgui->thumbnail_queue_size > 0));
|
||||
show_left_thumbnail = rgui->entry_has_left_thumbnail &&
|
||||
(mini_left_thumbnail.is_valid || (rgui->left_thumbnail_queue_size > 0));
|
||||
|
||||
/* Get maximum width of thumbnail 'panel' on right side
|
||||
* of screen */
|
||||
thumbnail_panel_width = rgui_get_mini_thumbnail_fullwidth();
|
||||
|
||||
if ((rgui->entry_has_thumbnail && rgui->thumbnail_queue_size > 0) ||
|
||||
(rgui->entry_has_left_thumbnail && rgui->left_thumbnail_queue_size > 0))
|
||||
thumbnail_panel_width = mini_thumbnail_max_width;
|
||||
|
||||
/* Index (relative to first displayed menu entry) of
|
||||
* the vertical centre of RGUI's 'terminal'
|
||||
* (required to determine whether a particular entry
|
||||
* is adjacent to the 'right' or 'left' thumbnail) */
|
||||
term_mid_point = (unsigned)((RGUI_TERM_HEIGHT(fb_height) * 0.5f) + 0.5f) - 1;
|
||||
}
|
||||
|
||||
/* Print title */
|
||||
title_buf[0] = '\0';
|
||||
@ -1694,9 +1828,9 @@ static void rgui_render(void *data, bool is_idle)
|
||||
x = RGUI_TERM_START_X(fb_width);
|
||||
y = RGUI_TERM_START_Y(fb_height);
|
||||
|
||||
menu_entries_ctl(MENU_ENTRIES_CTL_START_GET, &i);
|
||||
menu_entries_ctl(MENU_ENTRIES_CTL_START_GET, &new_start);
|
||||
|
||||
for (; i < end; i++, y += FONT_HEIGHT_STRIDE)
|
||||
for (i = new_start; i < end; i++, y += FONT_HEIGHT_STRIDE)
|
||||
{
|
||||
char entry_value[255];
|
||||
char message[255];
|
||||
@ -1727,9 +1861,45 @@ static void rgui_render(void *data, bool is_idle)
|
||||
entry_path = menu_entry_get_rich_label(&entry);
|
||||
menu_entry_get_value(&entry, entry_value, sizeof(entry_value));
|
||||
|
||||
/* Get base width of entry title field */
|
||||
/* Get base length of entry title field */
|
||||
entry_title_max_len = RGUI_TERM_WIDTH(fb_width) - (1 + 2);
|
||||
|
||||
/* If showing mini thumbnails, reduce title field length accordingly */
|
||||
if (show_mini_thumbnails)
|
||||
{
|
||||
unsigned term_offset = settings->bools.menu_rgui_swap_thumbnails ?
|
||||
(RGUI_TERM_HEIGHT(fb_height) - (i - new_start) - 1) : (i - new_start);
|
||||
unsigned thumbnail_width = 0;
|
||||
|
||||
/* Note:
|
||||
* - 'Right' thumbnail is drawn at the top
|
||||
* - 'Left' thumbnail is drawn at the bottom
|
||||
* ...unless thumbnail postions are swapped.
|
||||
* (legacy naming, unfortunately...) */
|
||||
|
||||
/* An annoyance - cannot assume terminal will have a
|
||||
* standard layout (even though it always will...),
|
||||
* so have to check whether there are an odd or even
|
||||
* number of entries... */
|
||||
if((RGUI_TERM_HEIGHT(fb_height) & 1) == 0)
|
||||
{
|
||||
/* Even number of entries */
|
||||
if ((show_thumbnail && (term_offset <= term_mid_point)) ||
|
||||
(show_left_thumbnail && (term_offset > term_mid_point)))
|
||||
thumbnail_width = thumbnail_panel_width;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Odd number of entries (will always be the case) */
|
||||
if ((show_thumbnail && (term_offset < term_mid_point)) ||
|
||||
(show_left_thumbnail && (term_offset > term_mid_point)) ||
|
||||
((show_thumbnail || show_left_thumbnail) && (term_offset == term_mid_point)))
|
||||
thumbnail_width = thumbnail_panel_width;
|
||||
}
|
||||
|
||||
entry_title_max_len -= (thumbnail_width / FONT_WIDTH_STRIDE) + 1;
|
||||
}
|
||||
|
||||
/* Determine whether entry has a value component */
|
||||
if (!string_is_empty(entry_value))
|
||||
{
|
||||
@ -1799,6 +1969,16 @@ static void rgui_render(void *data, bool is_idle)
|
||||
free(entry_path);
|
||||
}
|
||||
|
||||
/* Draw mini thumbnails, if required */
|
||||
if (show_mini_thumbnails)
|
||||
{
|
||||
if (show_thumbnail)
|
||||
rgui_render_mini_thumbnail(&mini_thumbnail, MENU_THUMBNAIL_RIGHT);
|
||||
|
||||
if (show_left_thumbnail)
|
||||
rgui_render_mini_thumbnail(&mini_left_thumbnail, MENU_THUMBNAIL_LEFT);
|
||||
}
|
||||
|
||||
/* Print menu sublabel/core name (if required) */
|
||||
if (settings->bools.menu_show_sublabels && !string_is_empty(rgui->menu_sublabel))
|
||||
{
|
||||
@ -1899,19 +2079,24 @@ static void rgui_framebuffer_free(void)
|
||||
rgui_frame_buf.data = NULL;
|
||||
}
|
||||
|
||||
static void rgui_thumbnail_free(void)
|
||||
static void rgui_thumbnail_free(thumbnail_t *thumbnail)
|
||||
{
|
||||
thumbnail.width = 0;
|
||||
thumbnail.height = 0;
|
||||
thumbnail.is_valid = false;
|
||||
if (!thumbnail)
|
||||
return;
|
||||
|
||||
if (!string_is_empty(thumbnail.path))
|
||||
free(thumbnail.path);
|
||||
thumbnail.path = NULL;
|
||||
thumbnail->max_width = 0;
|
||||
thumbnail->max_height = 0;
|
||||
thumbnail->width = 0;
|
||||
thumbnail->height = 0;
|
||||
thumbnail->is_valid = false;
|
||||
|
||||
if (thumbnail.data)
|
||||
free(thumbnail.data);
|
||||
thumbnail.data = NULL;
|
||||
if (!string_is_empty(thumbnail->path))
|
||||
free(thumbnail->path);
|
||||
thumbnail->path = NULL;
|
||||
|
||||
if (thumbnail->data)
|
||||
free(thumbnail->data);
|
||||
thumbnail->data = NULL;
|
||||
}
|
||||
|
||||
static void rgui_wallpaper_free(void)
|
||||
@ -2060,7 +2245,9 @@ static bool rgui_set_aspect_ratio(rgui_t *rgui, bool delay_update)
|
||||
settings_t *settings = config_get_ptr();
|
||||
|
||||
rgui_framebuffer_free();
|
||||
rgui_thumbnail_free();
|
||||
rgui_thumbnail_free(&fs_thumbnail);
|
||||
rgui_thumbnail_free(&mini_thumbnail);
|
||||
rgui_thumbnail_free(&mini_left_thumbnail);
|
||||
rgui_wallpaper_free();
|
||||
|
||||
/* Cache new aspect ratio */
|
||||
@ -2135,9 +2322,29 @@ static bool rgui_set_aspect_ratio(rgui_t *rgui, bool delay_update)
|
||||
rgui_term_layout.start_y = (rgui_frame_buf.height - (rgui_term_layout.height * FONT_HEIGHT_STRIDE)) / 2;
|
||||
|
||||
/* Allocate thumbnail buffer */
|
||||
thumbnail.data = (uint16_t*)calloc(
|
||||
rgui_frame_buf.width * rgui_frame_buf.height, sizeof(uint16_t));
|
||||
if (!thumbnail.data)
|
||||
fs_thumbnail.max_width = rgui_frame_buf.width;
|
||||
fs_thumbnail.max_height = rgui_frame_buf.height;
|
||||
fs_thumbnail.data = (uint16_t*)calloc(
|
||||
fs_thumbnail.max_width * fs_thumbnail.max_height, sizeof(uint16_t));
|
||||
if (!fs_thumbnail.data)
|
||||
return false;
|
||||
|
||||
/* Allocate mini thumbnail buffers */
|
||||
mini_thumbnail_max_width = ((rgui_term_layout.width - 4) > 19 ? 19 : (rgui_term_layout.width - 4)) * FONT_WIDTH_STRIDE;
|
||||
mini_thumbnail_max_height = (unsigned)((rgui_term_layout.height * FONT_HEIGHT_STRIDE) * 0.5f) - 2;
|
||||
|
||||
mini_thumbnail.max_width = mini_thumbnail_max_width;
|
||||
mini_thumbnail.max_height = mini_thumbnail_max_height;
|
||||
mini_thumbnail.data = (uint16_t*)calloc(
|
||||
mini_thumbnail.max_width * mini_thumbnail.max_height, sizeof(uint16_t));
|
||||
if (!mini_thumbnail.data)
|
||||
return false;
|
||||
|
||||
mini_left_thumbnail.max_width = mini_thumbnail_max_width;
|
||||
mini_left_thumbnail.max_height = mini_thumbnail_max_height;
|
||||
mini_left_thumbnail.data = (uint16_t*)calloc(
|
||||
mini_left_thumbnail.max_width * mini_left_thumbnail.max_height, sizeof(uint16_t));
|
||||
if (!mini_left_thumbnail.data)
|
||||
return false;
|
||||
|
||||
/* Allocate wallpaper buffer */
|
||||
@ -2223,14 +2430,17 @@ static void *rgui_init(void **userdata, bool video_is_threaded)
|
||||
goto error;
|
||||
|
||||
rgui->thumbnail_queue_size = 0;
|
||||
/* Ensure that we start with thumbnails disabled */
|
||||
rgui->show_thumbnail = false;
|
||||
rgui->left_thumbnail_queue_size = 0;
|
||||
/* Ensure that we start with fullscreen thumbnails disabled */
|
||||
rgui->show_fs_thumbnail = false;
|
||||
|
||||
return menu;
|
||||
|
||||
error:
|
||||
rgui_framebuffer_free();
|
||||
rgui_thumbnail_free();
|
||||
rgui_thumbnail_free(&fs_thumbnail);
|
||||
rgui_thumbnail_free(&mini_thumbnail);
|
||||
rgui_thumbnail_free(&mini_left_thumbnail);
|
||||
rgui_wallpaper_free();
|
||||
if (menu)
|
||||
free(menu);
|
||||
@ -2259,7 +2469,9 @@ static void rgui_free(void *data)
|
||||
menu_display_set_font_data_init(fb_font_inited);
|
||||
|
||||
rgui_framebuffer_free();
|
||||
rgui_thumbnail_free();
|
||||
rgui_thumbnail_free(&fs_thumbnail);
|
||||
rgui_thumbnail_free(&mini_thumbnail);
|
||||
rgui_thumbnail_free(&mini_left_thumbnail);
|
||||
rgui_wallpaper_free();
|
||||
|
||||
if (rgui_upscale_buf.data)
|
||||
@ -2442,21 +2654,50 @@ static void rgui_set_thumbnail_system(void *userdata, char *s, size_t len)
|
||||
|
||||
static void rgui_scan_selected_entry_thumbnail(rgui_t *rgui)
|
||||
{
|
||||
rgui->entry_has_thumbnail = false;
|
||||
settings_t *settings = config_get_ptr();
|
||||
|
||||
if (rgui->show_thumbnail && rgui->is_playlist)
|
||||
if (!settings)
|
||||
return;
|
||||
|
||||
rgui->entry_has_thumbnail = false;
|
||||
rgui->entry_has_left_thumbnail = false;
|
||||
|
||||
if ((rgui->show_fs_thumbnail || settings->bools.menu_rgui_inline_thumbnails) && rgui->is_playlist)
|
||||
{
|
||||
if (menu_thumbnail_set_content_playlist(rgui->thumbnail_path_data,
|
||||
playlist_get_cached(), menu_navigation_get_selection()))
|
||||
{
|
||||
if (menu_thumbnail_update_path(rgui->thumbnail_path_data, MENU_THUMBNAIL_RIGHT))
|
||||
if (menu_thumbnail_is_enabled(MENU_THUMBNAIL_RIGHT))
|
||||
{
|
||||
const char *thumbnail_path = NULL;
|
||||
|
||||
if (menu_thumbnail_get_path(rgui->thumbnail_path_data,
|
||||
MENU_THUMBNAIL_RIGHT, &thumbnail_path))
|
||||
if (menu_thumbnail_update_path(rgui->thumbnail_path_data, MENU_THUMBNAIL_RIGHT))
|
||||
{
|
||||
rgui->entry_has_thumbnail = request_thumbnail(rgui, thumbnail_path);
|
||||
const char *thumbnail_path = NULL;
|
||||
|
||||
if (menu_thumbnail_get_path(rgui->thumbnail_path_data,
|
||||
MENU_THUMBNAIL_RIGHT, &thumbnail_path))
|
||||
{
|
||||
if (rgui->show_fs_thumbnail)
|
||||
rgui->entry_has_thumbnail = request_thumbnail(
|
||||
&fs_thumbnail, MENU_THUMBNAIL_RIGHT, &rgui->thumbnail_queue_size, thumbnail_path);
|
||||
else
|
||||
rgui->entry_has_thumbnail = request_thumbnail(
|
||||
&mini_thumbnail, MENU_THUMBNAIL_RIGHT, &rgui->thumbnail_queue_size, thumbnail_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (settings->bools.menu_rgui_inline_thumbnails && menu_thumbnail_is_enabled(MENU_THUMBNAIL_LEFT))
|
||||
{
|
||||
if (menu_thumbnail_update_path(rgui->thumbnail_path_data, MENU_THUMBNAIL_LEFT))
|
||||
{
|
||||
const char *left_thumbnail_path = NULL;
|
||||
|
||||
if (menu_thumbnail_get_path(rgui->thumbnail_path_data,
|
||||
MENU_THUMBNAIL_LEFT, &left_thumbnail_path))
|
||||
{
|
||||
rgui->entry_has_left_thumbnail = request_thumbnail(
|
||||
&mini_left_thumbnail, MENU_THUMBNAIL_LEFT, &rgui->left_thumbnail_queue_size, left_thumbnail_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -2465,11 +2706,37 @@ static void rgui_scan_selected_entry_thumbnail(rgui_t *rgui)
|
||||
|
||||
static void rgui_update_thumbnail_image(void *userdata)
|
||||
{
|
||||
rgui_t *rgui = (rgui_t*)userdata;
|
||||
if (!rgui)
|
||||
rgui_t *rgui = (rgui_t*)userdata;
|
||||
settings_t *settings = config_get_ptr();
|
||||
if (!rgui || !settings)
|
||||
return;
|
||||
|
||||
rgui->show_thumbnail = !rgui->show_thumbnail;
|
||||
rgui->show_fs_thumbnail = !rgui->show_fs_thumbnail;
|
||||
|
||||
/* It is possible that we are waiting for a 'right' thumbnail
|
||||
* image to load at this point. If so, and we are displaying
|
||||
* inline thumbnails, then 'fs_thumbnail' and 'mini_thumbnail'
|
||||
* can get mixed up. To avoid this, we simply 'reset' the
|
||||
* currently inactive right thumbnail. */
|
||||
if (settings->bools.menu_rgui_inline_thumbnails)
|
||||
{
|
||||
if (rgui->show_fs_thumbnail)
|
||||
{
|
||||
mini_thumbnail.width = 0;
|
||||
mini_thumbnail.height = 0;
|
||||
mini_thumbnail.is_valid = false;
|
||||
free(mini_thumbnail.path);
|
||||
mini_thumbnail.path = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
fs_thumbnail.width = 0;
|
||||
fs_thumbnail.height = 0;
|
||||
fs_thumbnail.is_valid = false;
|
||||
free(fs_thumbnail.path);
|
||||
fs_thumbnail.path = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
rgui_scan_selected_entry_thumbnail(rgui);
|
||||
}
|
||||
@ -2590,8 +2857,7 @@ static void rgui_populate_entries(void *data,
|
||||
/* 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)) ||
|
||||
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));
|
||||
string_is_equal(label, msg_hash_to_str(MENU_ENUM_LABEL_DEFERRED_FAVORITES_LIST));
|
||||
|
||||
/* Set menu title */
|
||||
menu_entries_get_title(rgui->menu_title, sizeof(rgui->menu_title));
|
||||
|
@ -6211,6 +6211,10 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist
|
||||
MENU_ENUM_LABEL_MENU_USE_PREFERRED_SYSTEM_COLOR_THEME,
|
||||
PARSE_ONLY_BOOL, false) == 0)
|
||||
count++;
|
||||
if (menu_displaylist_parse_settings_enum(menu, info,
|
||||
MENU_ENUM_LABEL_MENU_RGUI_INLINE_THUMBNAILS,
|
||||
PARSE_ONLY_BOOL, false) == 0)
|
||||
count++;
|
||||
if (menu_displaylist_parse_settings_enum(menu, info,
|
||||
MENU_ENUM_LABEL_THUMBNAILS,
|
||||
PARSE_ONLY_UINT, false) == 0)
|
||||
@ -6223,6 +6227,10 @@ bool menu_displaylist_ctl(enum menu_displaylist_ctl_state type, menu_displaylist
|
||||
MENU_ENUM_LABEL_XMB_VERTICAL_THUMBNAILS,
|
||||
PARSE_ONLY_BOOL, false) == 0)
|
||||
count++;
|
||||
if (menu_displaylist_parse_settings_enum(menu, info,
|
||||
MENU_ENUM_LABEL_MENU_RGUI_SWAP_THUMBNAILS,
|
||||
PARSE_ONLY_BOOL, false) == 0)
|
||||
count++;
|
||||
if (menu_displaylist_parse_settings_enum(menu, info,
|
||||
MENU_ENUM_LABEL_MENU_RGUI_THUMBNAIL_DOWNSCALER,
|
||||
PARSE_ONLY_UINT, false) == 0)
|
||||
|
@ -9345,13 +9345,65 @@ static bool setting_append_list(
|
||||
general_read_handler,
|
||||
SD_FLAG_ADVANCED);
|
||||
|
||||
if (string_is_equal(settings->arrays.menu_driver, "rgui"))
|
||||
{
|
||||
CONFIG_BOOL(
|
||||
list, list_info,
|
||||
&settings->bools.menu_rgui_inline_thumbnails,
|
||||
MENU_ENUM_LABEL_MENU_RGUI_INLINE_THUMBNAILS,
|
||||
MENU_ENUM_LABEL_VALUE_MENU_RGUI_INLINE_THUMBNAILS,
|
||||
rgui_inline_thumbnails,
|
||||
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);
|
||||
|
||||
CONFIG_BOOL(
|
||||
list, list_info,
|
||||
&settings->bools.menu_rgui_swap_thumbnails,
|
||||
MENU_ENUM_LABEL_MENU_RGUI_SWAP_THUMBNAILS,
|
||||
MENU_ENUM_LABEL_VALUE_MENU_RGUI_SWAP_THUMBNAILS,
|
||||
rgui_swap_thumbnails,
|
||||
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);
|
||||
}
|
||||
|
||||
if (string_is_equal(settings->arrays.menu_driver, "xmb") || string_is_equal(settings->arrays.menu_driver, "ozone") || string_is_equal(settings->arrays.menu_driver, "rgui"))
|
||||
{
|
||||
enum msg_hash_enums thumbnails_label_value;
|
||||
enum msg_hash_enums left_thumbnails_label_value;
|
||||
|
||||
if (string_is_equal(settings->arrays.menu_driver, "rgui"))
|
||||
{
|
||||
thumbnails_label_value = MENU_ENUM_LABEL_VALUE_THUMBNAILS_RGUI;
|
||||
left_thumbnails_label_value = MENU_ENUM_LABEL_VALUE_LEFT_THUMBNAILS_RGUI;
|
||||
}
|
||||
else if (string_is_equal(settings->arrays.menu_driver, "ozone"))
|
||||
{
|
||||
thumbnails_label_value = MENU_ENUM_LABEL_VALUE_THUMBNAILS;
|
||||
left_thumbnails_label_value = MENU_ENUM_LABEL_VALUE_LEFT_THUMBNAILS_OZONE;
|
||||
}
|
||||
else
|
||||
{
|
||||
thumbnails_label_value = MENU_ENUM_LABEL_VALUE_THUMBNAILS;
|
||||
left_thumbnails_label_value = MENU_ENUM_LABEL_VALUE_LEFT_THUMBNAILS;
|
||||
}
|
||||
|
||||
CONFIG_UINT(
|
||||
list, list_info,
|
||||
&settings->uints.menu_thumbnails,
|
||||
MENU_ENUM_LABEL_THUMBNAILS,
|
||||
MENU_ENUM_LABEL_VALUE_THUMBNAILS,
|
||||
thumbnails_label_value,
|
||||
menu_thumbnails_default,
|
||||
&group_info,
|
||||
&subgroup_info,
|
||||
@ -9362,6 +9414,40 @@ static bool setting_append_list(
|
||||
(*list)[list_info->index - 1].get_string_representation =
|
||||
&setting_get_string_representation_uint_menu_thumbnails;
|
||||
menu_settings_list_current_add_range(list, list_info, 0, 3, 1, true, true);
|
||||
|
||||
CONFIG_UINT(
|
||||
list, list_info,
|
||||
&settings->uints.menu_left_thumbnails,
|
||||
MENU_ENUM_LABEL_LEFT_THUMBNAILS,
|
||||
left_thumbnails_label_value,
|
||||
menu_left_thumbnails_default,
|
||||
&group_info,
|
||||
&subgroup_info,
|
||||
parent_group,
|
||||
general_write_handler,
|
||||
general_read_handler);
|
||||
(*list)[list_info->index - 1].action_ok = &setting_action_ok_uint;
|
||||
(*list)[list_info->index - 1].get_string_representation =
|
||||
&setting_get_string_representation_uint_menu_left_thumbnails;
|
||||
menu_settings_list_current_add_range(list, list_info, 0, 3, 1, true, true);
|
||||
}
|
||||
|
||||
if (string_is_equal(settings->arrays.menu_driver, "xmb"))
|
||||
{
|
||||
CONFIG_BOOL(
|
||||
list, list_info,
|
||||
&settings->bools.menu_xmb_vertical_thumbnails,
|
||||
MENU_ENUM_LABEL_XMB_VERTICAL_THUMBNAILS,
|
||||
MENU_ENUM_LABEL_VALUE_XMB_VERTICAL_THUMBNAILS,
|
||||
xmb_vertical_thumbnails,
|
||||
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);
|
||||
}
|
||||
|
||||
if (string_is_equal(settings->arrays.menu_driver, "rgui"))
|
||||
@ -9383,45 +9469,6 @@ static bool setting_append_list(
|
||||
menu_settings_list_current_add_range(list, list_info, 0, RGUI_THUMB_SCALE_LAST-1, 1, true, true);
|
||||
}
|
||||
|
||||
if (string_is_equal(settings->arrays.menu_driver, "xmb") || string_is_equal(settings->arrays.menu_driver, "ozone"))
|
||||
{
|
||||
bool is_ozone = string_is_equal(settings->arrays.menu_driver, "ozone");
|
||||
enum msg_hash_enums label = is_ozone ?
|
||||
MENU_ENUM_LABEL_VALUE_LEFT_THUMBNAILS_OZONE : MENU_ENUM_LABEL_VALUE_LEFT_THUMBNAILS;
|
||||
|
||||
CONFIG_UINT(
|
||||
list, list_info,
|
||||
&settings->uints.menu_left_thumbnails,
|
||||
MENU_ENUM_LABEL_LEFT_THUMBNAILS,
|
||||
label,
|
||||
menu_left_thumbnails_default,
|
||||
&group_info,
|
||||
&subgroup_info,
|
||||
parent_group,
|
||||
general_write_handler,
|
||||
general_read_handler);
|
||||
(*list)[list_info->index - 1].action_ok = &setting_action_ok_uint;
|
||||
(*list)[list_info->index - 1].get_string_representation =
|
||||
&setting_get_string_representation_uint_menu_left_thumbnails;
|
||||
menu_settings_list_current_add_range(list, list_info, 0, 3, 1, true, true);
|
||||
|
||||
if (!is_ozone)
|
||||
CONFIG_BOOL(
|
||||
list, list_info,
|
||||
&settings->bools.menu_xmb_vertical_thumbnails,
|
||||
MENU_ENUM_LABEL_XMB_VERTICAL_THUMBNAILS,
|
||||
MENU_ENUM_LABEL_VALUE_XMB_VERTICAL_THUMBNAILS,
|
||||
xmb_vertical_thumbnails,
|
||||
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);
|
||||
}
|
||||
|
||||
CONFIG_BOOL(
|
||||
list, list_info,
|
||||
&settings->bools.menu_timedate_enable,
|
||||
|
@ -901,9 +901,13 @@ enum msg_hash_enums
|
||||
MENU_LABEL(CONTENT_SHOW_PLAYLISTS),
|
||||
MENU_LABEL(XMB_RIBBON_ENABLE),
|
||||
MENU_LABEL(THUMBNAILS),
|
||||
MENU_LABEL(THUMBNAILS_RGUI),
|
||||
MENU_LABEL(LEFT_THUMBNAILS),
|
||||
MENU_LABEL(LEFT_THUMBNAILS_RGUI),
|
||||
MENU_LABEL(LEFT_THUMBNAILS_OZONE),
|
||||
MENU_LABEL(XMB_VERTICAL_THUMBNAILS),
|
||||
MENU_LABEL(MENU_RGUI_INLINE_THUMBNAILS),
|
||||
MENU_LABEL(MENU_RGUI_SWAP_THUMBNAILS),
|
||||
MENU_LABEL(MENU_RGUI_THUMBNAIL_DOWNSCALER),
|
||||
MENU_LABEL(TIMEDATE_ENABLE),
|
||||
MENU_LABEL(TIMEDATE_STYLE),
|
||||
|
Loading…
Reference in New Issue
Block a user