mirror of
https://github.com/libretro/RetroArch
synced 2025-01-30 03:32:46 +00:00
(GLUI) Add initial thumbnail support
This commit is contained in:
parent
d4b7be4ae4
commit
c356969c3a
@ -829,6 +829,7 @@ ifeq ($(HAVE_MENU_COMMON), 1)
|
||||
menu/drivers/menu_generic.o \
|
||||
menu/drivers/null.o \
|
||||
menu/menu_thumbnail_path.o \
|
||||
menu/menu_thumbnail.o \
|
||||
menu/drivers_display/menu_display_null.o
|
||||
|
||||
ifeq ($(HAVE_MENU_WIDGETS), 1)
|
||||
|
@ -141,6 +141,11 @@
|
||||
* of screen space when using landscape layouts */
|
||||
#define DEFAULT_MATERIALUI_AUTO_ROTATE_NAV_BAR true
|
||||
|
||||
/* Default portrait/landscape playlist view modes
|
||||
* (when thumbnails are enabled) */
|
||||
#define DEFAULT_MATERIALUI_THUMBNAIL_VIEW_PORTRAIT MATERIALUI_THUMBNAIL_VIEW_PORTRAIT_DISABLED
|
||||
#define DEFAULT_MATERIALUI_THUMBNAIL_VIEW_LANDSCAPE MATERIALUI_THUMBNAIL_VIEW_LANDSCAPE_DISABLED
|
||||
|
||||
#define DEFAULT_CRT_SWITCH_RESOLUTION CRT_SWITCH_NONE
|
||||
|
||||
#define DEFAULT_CRT_SWITCH_RESOLUTION_SUPER 2560
|
||||
|
@ -1812,6 +1812,8 @@ static struct config_uint_setting *populate_settings_uint(settings_t *settings,
|
||||
#endif
|
||||
SETTING_UINT("materialui_menu_color_theme", &settings->uints.menu_materialui_color_theme, true, DEFAULT_MATERIALUI_THEME, false);
|
||||
SETTING_UINT("materialui_menu_transition_animation", &settings->uints.menu_materialui_transition_animation, true, DEFAULT_MATERIALUI_TRANSITION_ANIM, false);
|
||||
SETTING_UINT("materialui_thumbnail_view_portrait", &settings->uints.menu_materialui_thumbnail_view_portrait, true, DEFAULT_MATERIALUI_THUMBNAIL_VIEW_PORTRAIT, false);
|
||||
SETTING_UINT("materialui_thumbnail_view_landscape", &settings->uints.menu_materialui_thumbnail_view_landscape, true, DEFAULT_MATERIALUI_THUMBNAIL_VIEW_LANDSCAPE, false);
|
||||
SETTING_UINT("menu_shader_pipeline", &settings->uints.menu_xmb_shader_pipeline, true, DEFAULT_MENU_SHADER_PIPELINE, false);
|
||||
#ifdef HAVE_OZONE
|
||||
SETTING_UINT("ozone_menu_color_theme", &settings->uints.menu_ozone_color_theme, true, 1, false);
|
||||
|
@ -535,6 +535,8 @@ typedef struct settings
|
||||
unsigned menu_xmb_thumbnail_scale_factor;
|
||||
unsigned menu_materialui_color_theme;
|
||||
unsigned menu_materialui_transition_animation;
|
||||
unsigned menu_materialui_thumbnail_view_portrait;
|
||||
unsigned menu_materialui_thumbnail_view_landscape;
|
||||
unsigned menu_ozone_color_theme;
|
||||
unsigned menu_font_color_red;
|
||||
unsigned menu_font_color_green;
|
||||
|
@ -1271,6 +1271,7 @@ MENU
|
||||
#include "../menu/menu_displaylist.c"
|
||||
#include "../menu/menu_animation.c"
|
||||
#include "../menu/menu_thumbnail_path.c"
|
||||
#include "../menu/menu_thumbnail.c"
|
||||
|
||||
#include "../menu/drivers/null.c"
|
||||
#include "../menu/drivers/menu_generic.c"
|
||||
|
@ -729,6 +729,10 @@ MSG_HASH(MENU_ENUM_LABEL_MATERIALUI_MENU_COLOR_THEME,
|
||||
"materialui_menu_color_theme")
|
||||
MSG_HASH(MENU_ENUM_LABEL_MATERIALUI_MENU_TRANSITION_ANIMATION,
|
||||
"materialui_menu_transition_animation")
|
||||
MSG_HASH(MENU_ENUM_LABEL_MATERIALUI_MENU_THUMBNAIL_VIEW_PORTRAIT,
|
||||
"materialui_thumbnail_view_portrait")
|
||||
MSG_HASH(MENU_ENUM_LABEL_MATERIALUI_MENU_THUMBNAIL_VIEW_LANDSCAPE,
|
||||
"materialui_thumbnail_view_landscape")
|
||||
MSG_HASH(MENU_ENUM_LABEL_MATERIALUI_MENU_FOOTER_OPACITY,
|
||||
"materialui_menu_footer_opacity")
|
||||
MSG_HASH(MENU_ENUM_LABEL_MATERIALUI_MENU_HEADER_OPACITY,
|
||||
|
@ -1651,6 +1651,10 @@ MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_HISTORY,
|
||||
"Load Recent"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_LOAD_CONTENT_HISTORY,
|
||||
"Select content from recent history playlist."
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_LOAD_CONTENT_LIST,
|
||||
"Load Content"
|
||||
@ -1819,6 +1823,50 @@ MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_TRANSITION_ANIM_NONE,
|
||||
"OFF"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_THUMBNAIL_VIEW_PORTRAIT,
|
||||
"Portrait Thumbnail View"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_MATERIALUI_MENU_THUMBNAIL_VIEW_PORTRAIT,
|
||||
"Specify playlist thumbnail view mode when using portrait display orientations."
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_THUMBNAIL_VIEW_LANDSCAPE,
|
||||
"Landscape Thumbnail View"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_SUBLABEL_MATERIALUI_MENU_THUMBNAIL_VIEW_LANDSCAPE,
|
||||
"Specify playlist thumbnail view mode when using landscape display orientations."
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_MATERIALUI_THUMBNAIL_VIEW_PORTRAIT_DISABLED,
|
||||
"OFF"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_MATERIALUI_THUMBNAIL_VIEW_PORTRAIT_LIST_SMALL,
|
||||
"List (Small)"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_MATERIALUI_THUMBNAIL_VIEW_PORTRAIT_LIST_MEDIUM,
|
||||
"List (Medium)"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_MATERIALUI_THUMBNAIL_VIEW_LANDSCAPE_DISABLED,
|
||||
"OFF"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_MATERIALUI_THUMBNAIL_VIEW_LANDSCAPE_LIST_SMALL,
|
||||
"List (Small)"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_MATERIALUI_THUMBNAIL_VIEW_LANDSCAPE_LIST_MEDIUM,
|
||||
"List (Medium)"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_MATERIALUI_THUMBNAIL_VIEW_LANDSCAPE_LIST_LARGE,
|
||||
"List (Large)"
|
||||
)
|
||||
MSG_HASH(
|
||||
MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_FOOTER_OPACITY,
|
||||
"Footer Opacity"
|
||||
|
@ -108,9 +108,13 @@ int action_switch_thumbnail(const char *path,
|
||||
if (settings->uints.menu_thumbnails == 0)
|
||||
{
|
||||
/* 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"))
|
||||
* toggling thumbnail view on/off.
|
||||
* GLUI is a special case where thumbnail 'switch' corresponds to
|
||||
* changing thumbnail view mode.
|
||||
* For other menu drivers, we cycle through available thumbnail
|
||||
* types. */
|
||||
if(!string_is_equal(settings->arrays.menu_driver, "rgui") &&
|
||||
!string_is_equal(settings->arrays.menu_driver, "glui"))
|
||||
{
|
||||
settings->uints.menu_left_thumbnails++;
|
||||
if (settings->uints.menu_left_thumbnails > 3)
|
||||
@ -122,9 +126,13 @@ int action_switch_thumbnail(const char *path,
|
||||
else
|
||||
{
|
||||
/* 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"))
|
||||
* toggling thumbnail view on/off.
|
||||
* GLUI is a special case where thumbnail 'switch' corresponds to
|
||||
* changing thumbnail view mode.
|
||||
* For other menu drivers, we cycle through available thumbnail
|
||||
* types. */
|
||||
if(!string_is_equal(settings->arrays.menu_driver, "rgui") &&
|
||||
!string_is_equal(settings->arrays.menu_driver, "glui"))
|
||||
{
|
||||
settings->uints.menu_thumbnails++;
|
||||
if (settings->uints.menu_thumbnails > 3)
|
||||
|
@ -278,6 +278,7 @@ default_sublabel_macro(action_bind_sublabel_load_disc, MENU_ENU
|
||||
default_sublabel_macro(action_bind_sublabel_dump_disc, MENU_ENUM_SUBLABEL_DUMP_DISC)
|
||||
default_sublabel_macro(action_bind_sublabel_content_list, MENU_ENUM_SUBLABEL_LOAD_CONTENT_LIST)
|
||||
default_sublabel_macro(action_bind_sublabel_content_special, MENU_ENUM_SUBLABEL_LOAD_CONTENT_SPECIAL)
|
||||
default_sublabel_macro(action_bind_sublabel_load_content_history, MENU_ENUM_SUBLABEL_LOAD_CONTENT_HISTORY)
|
||||
default_sublabel_macro(action_bind_sublabel_network_information, MENU_ENUM_SUBLABEL_NETWORK_INFORMATION)
|
||||
default_sublabel_macro(action_bind_sublabel_system_information, MENU_ENUM_SUBLABEL_SYSTEM_INFORMATION)
|
||||
default_sublabel_macro(action_bind_sublabel_quit_retroarch, MENU_ENUM_SUBLABEL_QUIT_RETROARCH)
|
||||
@ -489,6 +490,8 @@ default_sublabel_macro(action_bind_sublabel_xmb_vertical_thumbnails,
|
||||
default_sublabel_macro(action_bind_sublabel_menu_xmb_thumbnail_scale_factor, MENU_ENUM_SUBLABEL_MENU_XMB_THUMBNAIL_SCALE_FACTOR)
|
||||
default_sublabel_macro(action_bind_sublabel_menu_color_theme, MENU_ENUM_SUBLABEL_MATERIALUI_MENU_COLOR_THEME)
|
||||
default_sublabel_macro(action_bind_sublabel_materialui_menu_transition_animation, MENU_ENUM_SUBLABEL_MATERIALUI_MENU_TRANSITION_ANIMATION)
|
||||
default_sublabel_macro(action_bind_sublabel_materialui_menu_thumbnail_view_portrait, MENU_ENUM_SUBLABEL_MATERIALUI_MENU_THUMBNAIL_VIEW_PORTRAIT)
|
||||
default_sublabel_macro(action_bind_sublabel_materialui_menu_thumbnail_view_landscape, MENU_ENUM_SUBLABEL_MATERIALUI_MENU_THUMBNAIL_VIEW_LANDSCAPE)
|
||||
default_sublabel_macro(action_bind_sublabel_ozone_menu_color_theme, MENU_ENUM_SUBLABEL_OZONE_MENU_COLOR_THEME)
|
||||
default_sublabel_macro(action_bind_sublabel_ozone_collapse_sidebar, MENU_ENUM_SUBLABEL_OZONE_COLLAPSE_SIDEBAR)
|
||||
default_sublabel_macro(action_bind_sublabel_ozone_truncate_playlist_name, MENU_ENUM_SUBLABEL_OZONE_TRUNCATE_PLAYLIST_NAME)
|
||||
@ -1721,6 +1724,12 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
|
||||
case MENU_ENUM_LABEL_MATERIALUI_MENU_TRANSITION_ANIMATION:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_materialui_menu_transition_animation);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_MATERIALUI_MENU_THUMBNAIL_VIEW_PORTRAIT:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_materialui_menu_thumbnail_view_portrait);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_MATERIALUI_MENU_THUMBNAIL_VIEW_LANDSCAPE:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_materialui_menu_thumbnail_view_landscape);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_XMB_SHADOWS_ENABLE:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_xmb_shadows_enable);
|
||||
break;
|
||||
@ -2352,6 +2361,9 @@ int menu_cbs_init_bind_sublabel(menu_file_list_cbs_t *cbs,
|
||||
case MENU_ENUM_LABEL_LOAD_CONTENT_SPECIAL:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_content_special);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_LOAD_CONTENT_HISTORY:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_load_content_history);
|
||||
break;
|
||||
case MENU_ENUM_LABEL_START_CORE:
|
||||
BIND_ACTION_SUBLABEL(cbs, action_bind_sublabel_start_core);
|
||||
break;
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -458,7 +458,7 @@ static void ozone_update_thumbnail_image(void *data)
|
||||
#endif
|
||||
}
|
||||
|
||||
static void ozone_refresh_thumbnail_image(void *data)
|
||||
static void ozone_refresh_thumbnail_image(void *data, unsigned i)
|
||||
{
|
||||
ozone_handle_t *ozone = (ozone_handle_t*)data;
|
||||
|
||||
|
@ -4635,7 +4635,7 @@ static void rgui_update_thumbnail_image(void *userdata)
|
||||
rgui_scan_selected_entry_thumbnail(rgui, true);
|
||||
}
|
||||
|
||||
static void rgui_refresh_thumbnail_image(void *userdata)
|
||||
static void rgui_refresh_thumbnail_image(void *userdata, unsigned i)
|
||||
{
|
||||
rgui_t *rgui = (rgui_t*)userdata;
|
||||
settings_t *settings = config_get_ptr();
|
||||
|
@ -1086,7 +1086,7 @@ static void stripes_update_thumbnail_image(void *data)
|
||||
}
|
||||
}
|
||||
|
||||
static void stripes_refresh_thumbnail_image(void *data)
|
||||
static void stripes_refresh_thumbnail_image(void *data, unsigned i)
|
||||
{
|
||||
stripes_update_thumbnail_image(data);
|
||||
}
|
||||
|
@ -1082,7 +1082,7 @@ static unsigned xmb_get_system_tab(xmb_handle_t *xmb, unsigned i)
|
||||
return UINT_MAX;
|
||||
}
|
||||
|
||||
static void xmb_refresh_thumbnail_image(void *data)
|
||||
static void xmb_refresh_thumbnail_image(void *data, unsigned i)
|
||||
{
|
||||
xmb_handle_t *xmb = (xmb_handle_t*)data;
|
||||
|
||||
|
@ -177,6 +177,23 @@ enum materialui_transition_animation
|
||||
MATERIALUI_TRANSITION_ANIM_LAST
|
||||
};
|
||||
|
||||
enum materialui_thumbnail_view_portrait
|
||||
{
|
||||
MATERIALUI_THUMBNAIL_VIEW_PORTRAIT_DISABLED = 0,
|
||||
MATERIALUI_THUMBNAIL_VIEW_PORTRAIT_LIST_SMALL,
|
||||
MATERIALUI_THUMBNAIL_VIEW_PORTRAIT_LIST_MEDIUM,
|
||||
MATERIALUI_THUMBNAIL_VIEW_PORTRAIT_LAST
|
||||
};
|
||||
|
||||
enum materialui_thumbnail_view_landscape
|
||||
{
|
||||
MATERIALUI_THUMBNAIL_VIEW_LANDSCAPE_DISABLED = 0,
|
||||
MATERIALUI_THUMBNAIL_VIEW_LANDSCAPE_LIST_SMALL,
|
||||
MATERIALUI_THUMBNAIL_VIEW_LANDSCAPE_LIST_MEDIUM,
|
||||
MATERIALUI_THUMBNAIL_VIEW_LANDSCAPE_LIST_LARGE,
|
||||
MATERIALUI_THUMBNAIL_VIEW_LANDSCAPE_LAST
|
||||
};
|
||||
|
||||
enum xmb_color_theme
|
||||
{
|
||||
XMB_THEME_LEGACY_RED = 0,
|
||||
|
@ -1129,9 +1129,11 @@ static int menu_displaylist_parse_database_entry(menu_handle_t *menu,
|
||||
* 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
|
||||
* RGUI and GLUI, since this functionality is handled elsewhere
|
||||
* (and doing it here creates harmful conflicts) */
|
||||
if ((i == 0) && !string_is_equal(settings->arrays.menu_driver, "rgui"))
|
||||
if ((i == 0) &&
|
||||
!string_is_equal(settings->arrays.menu_driver, "rgui") &&
|
||||
!string_is_equal(settings->arrays.menu_driver, "glui"))
|
||||
{
|
||||
if (!string_is_empty(db_info_entry->name))
|
||||
strlcpy(thumbnail_content, db_info_entry->name,
|
||||
@ -2831,11 +2833,12 @@ static bool menu_displaylist_parse_playlist_manager_settings(
|
||||
MENU_SETTING_PLAYLIST_MANAGER_RIGHT_THUMBNAIL_MODE, 0, 0);
|
||||
|
||||
/* > Left thumbnail mode */
|
||||
menu_entries_append_enum(info->list,
|
||||
msg_hash_to_str(left_thumbnail_label_value),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_PLAYLIST_MANAGER_LEFT_THUMBNAIL_MODE),
|
||||
MENU_ENUM_LABEL_PLAYLIST_MANAGER_LEFT_THUMBNAIL_MODE,
|
||||
MENU_SETTING_PLAYLIST_MANAGER_LEFT_THUMBNAIL_MODE, 0, 0);
|
||||
if (!string_is_equal(settings->arrays.menu_driver, "glui"))
|
||||
menu_entries_append_enum(info->list,
|
||||
msg_hash_to_str(left_thumbnail_label_value),
|
||||
msg_hash_to_str(MENU_ENUM_LABEL_PLAYLIST_MANAGER_LEFT_THUMBNAIL_MODE),
|
||||
MENU_ENUM_LABEL_PLAYLIST_MANAGER_LEFT_THUMBNAIL_MODE,
|
||||
MENU_SETTING_PLAYLIST_MANAGER_LEFT_THUMBNAIL_MODE, 0, 0);
|
||||
|
||||
/* TODO - Add:
|
||||
* - Remove invalid entries */
|
||||
@ -5454,6 +5457,8 @@ unsigned menu_displaylist_build_list(file_list_t *list, enum menu_displaylist_ct
|
||||
{MENU_ENUM_LABEL_MATERIALUI_MENU_FOOTER_OPACITY, PARSE_ONLY_FLOAT},
|
||||
{MENU_ENUM_LABEL_MENU_USE_PREFERRED_SYSTEM_COLOR_THEME, PARSE_ONLY_BOOL },
|
||||
{MENU_ENUM_LABEL_MENU_RGUI_INLINE_THUMBNAILS, PARSE_ONLY_BOOL },
|
||||
{MENU_ENUM_LABEL_MATERIALUI_MENU_THUMBNAIL_VIEW_PORTRAIT, PARSE_ONLY_UINT },
|
||||
{MENU_ENUM_LABEL_MATERIALUI_MENU_THUMBNAIL_VIEW_LANDSCAPE, PARSE_ONLY_UINT },
|
||||
{MENU_ENUM_LABEL_THUMBNAILS, PARSE_ONLY_UINT },
|
||||
{MENU_ENUM_LABEL_LEFT_THUMBNAILS, PARSE_ONLY_UINT },
|
||||
{MENU_ENUM_LABEL_XMB_VERTICAL_THUMBNAILS, PARSE_ONLY_BOOL },
|
||||
|
@ -3845,9 +3845,11 @@ bool menu_driver_ctl(enum rarch_menu_ctl_state state, void *data)
|
||||
break;
|
||||
case RARCH_MENU_CTL_REFRESH_THUMBNAIL_IMAGE:
|
||||
{
|
||||
if (!menu_driver_ctx || !menu_driver_ctx->refresh_thumbnail_image)
|
||||
unsigned *i = (unsigned*)data;
|
||||
|
||||
if (!i || !menu_driver_ctx || !menu_driver_ctx->refresh_thumbnail_image)
|
||||
return false;
|
||||
menu_driver_ctx->refresh_thumbnail_image(menu_userdata);
|
||||
menu_driver_ctx->refresh_thumbnail_image(menu_userdata, *i);
|
||||
}
|
||||
break;
|
||||
case RARCH_MENU_CTL_UPDATE_SAVESTATE_THUMBNAIL_PATH:
|
||||
|
@ -309,7 +309,7 @@ typedef struct menu_ctx_driver
|
||||
int (*environ_cb)(enum menu_environ_cb type, void *data, void *userdata);
|
||||
void (*update_thumbnail_path)(void *data, unsigned i, char pos);
|
||||
void (*update_thumbnail_image)(void *data);
|
||||
void (*refresh_thumbnail_image)(void *data);
|
||||
void (*refresh_thumbnail_image)(void *data, unsigned i);
|
||||
void (*set_thumbnail_system)(void *data, char* s, size_t len);
|
||||
void (*get_thumbnail_system)(void *data, char* s, size_t len);
|
||||
void (*set_thumbnail_content)(void *data, const char *s);
|
||||
|
@ -3961,6 +3961,69 @@ static void setting_get_string_representation_uint_materialui_menu_transition_an
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void setting_get_string_representation_uint_materialui_menu_thumbnail_view_portrait(
|
||||
rarch_setting_t *setting,
|
||||
char *s, size_t len)
|
||||
{
|
||||
if (!setting)
|
||||
return;
|
||||
|
||||
switch (*setting->value.target.unsigned_integer)
|
||||
{
|
||||
case MATERIALUI_THUMBNAIL_VIEW_PORTRAIT_DISABLED:
|
||||
strlcpy(s,
|
||||
msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_MATERIALUI_THUMBNAIL_VIEW_PORTRAIT_DISABLED), len);
|
||||
break;
|
||||
case MATERIALUI_THUMBNAIL_VIEW_PORTRAIT_LIST_SMALL:
|
||||
strlcpy(s,
|
||||
msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_MATERIALUI_THUMBNAIL_VIEW_PORTRAIT_LIST_SMALL), len);
|
||||
break;
|
||||
case MATERIALUI_THUMBNAIL_VIEW_PORTRAIT_LIST_MEDIUM:
|
||||
strlcpy(s,
|
||||
msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_MATERIALUI_THUMBNAIL_VIEW_PORTRAIT_LIST_MEDIUM), len);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void setting_get_string_representation_uint_materialui_menu_thumbnail_view_landscape(
|
||||
rarch_setting_t *setting,
|
||||
char *s, size_t len)
|
||||
{
|
||||
if (!setting)
|
||||
return;
|
||||
|
||||
switch (*setting->value.target.unsigned_integer)
|
||||
{
|
||||
case MATERIALUI_THUMBNAIL_VIEW_LANDSCAPE_DISABLED:
|
||||
strlcpy(s,
|
||||
msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_MATERIALUI_THUMBNAIL_VIEW_LANDSCAPE_DISABLED), len);
|
||||
break;
|
||||
case MATERIALUI_THUMBNAIL_VIEW_LANDSCAPE_LIST_SMALL:
|
||||
strlcpy(s,
|
||||
msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_MATERIALUI_THUMBNAIL_VIEW_LANDSCAPE_LIST_SMALL), len);
|
||||
break;
|
||||
case MATERIALUI_THUMBNAIL_VIEW_LANDSCAPE_LIST_MEDIUM:
|
||||
strlcpy(s,
|
||||
msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_MATERIALUI_THUMBNAIL_VIEW_LANDSCAPE_LIST_MEDIUM), len);
|
||||
break;
|
||||
case MATERIALUI_THUMBNAIL_VIEW_LANDSCAPE_LIST_LARGE:
|
||||
strlcpy(s,
|
||||
msg_hash_to_str(
|
||||
MENU_ENUM_LABEL_VALUE_MATERIALUI_THUMBNAIL_VIEW_LANDSCAPE_LIST_LARGE), len);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_XMB
|
||||
@ -13012,6 +13075,40 @@ static bool setting_append_list(
|
||||
general_read_handler,
|
||||
SD_FLAG_NONE);
|
||||
|
||||
CONFIG_UINT(
|
||||
list, list_info,
|
||||
&settings->uints.menu_materialui_thumbnail_view_portrait,
|
||||
MENU_ENUM_LABEL_MATERIALUI_MENU_THUMBNAIL_VIEW_PORTRAIT,
|
||||
MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_THUMBNAIL_VIEW_PORTRAIT,
|
||||
DEFAULT_MATERIALUI_THUMBNAIL_VIEW_PORTRAIT,
|
||||
&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_materialui_menu_thumbnail_view_portrait;
|
||||
menu_settings_list_current_add_range(list, list_info, 0, MATERIALUI_THUMBNAIL_VIEW_PORTRAIT_LAST-1, 1, true, true);
|
||||
(*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_COMBOBOX;
|
||||
|
||||
CONFIG_UINT(
|
||||
list, list_info,
|
||||
&settings->uints.menu_materialui_thumbnail_view_landscape,
|
||||
MENU_ENUM_LABEL_MATERIALUI_MENU_THUMBNAIL_VIEW_LANDSCAPE,
|
||||
MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_THUMBNAIL_VIEW_LANDSCAPE,
|
||||
DEFAULT_MATERIALUI_THUMBNAIL_VIEW_LANDSCAPE,
|
||||
&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_materialui_menu_thumbnail_view_landscape;
|
||||
menu_settings_list_current_add_range(list, list_info, 0, MATERIALUI_THUMBNAIL_VIEW_LANDSCAPE_LAST-1, 1, true, true);
|
||||
(*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_COMBOBOX;
|
||||
|
||||
/* TODO: These should be removed entirely, but just
|
||||
* comment out for now in case users complain...
|
||||
CONFIG_FLOAT(
|
||||
@ -13149,7 +13246,10 @@ static bool setting_append_list(
|
||||
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"))
|
||||
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") ||
|
||||
string_is_equal(settings->arrays.menu_driver, "glui"))
|
||||
{
|
||||
enum msg_hash_enums thumbnails_label_value;
|
||||
enum msg_hash_enums left_thumbnails_label_value;
|
||||
@ -13187,22 +13287,26 @@ static bool setting_append_list(
|
||||
menu_settings_list_current_add_range(list, list_info, 0, 3, 1, true, true);
|
||||
(*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_RADIO_BUTTONS;
|
||||
|
||||
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);
|
||||
(*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_RADIO_BUTTONS;
|
||||
/* Material UI does not use left thumbnails (yet...) */
|
||||
if (!string_is_equal(settings->arrays.menu_driver, "glui"))
|
||||
{
|
||||
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);
|
||||
(*list)[list_info->index - 1].ui_type = ST_UI_TYPE_UINT_RADIO_BUTTONS;
|
||||
}
|
||||
}
|
||||
|
||||
if (string_is_equal(settings->arrays.menu_driver, "xmb"))
|
||||
@ -13238,7 +13342,9 @@ static bool setting_append_list(
|
||||
menu_settings_list_current_add_range(list, list_info, (*list)[list_info->index - 1].offset_by, 100, 1, true, true);
|
||||
}
|
||||
|
||||
if (string_is_equal(settings->arrays.menu_driver, "xmb") || string_is_equal(settings->arrays.menu_driver, "ozone"))
|
||||
if (string_is_equal(settings->arrays.menu_driver, "xmb") ||
|
||||
string_is_equal(settings->arrays.menu_driver, "ozone") ||
|
||||
string_is_equal(settings->arrays.menu_driver, "glui"))
|
||||
{
|
||||
CONFIG_UINT(
|
||||
list, list_info,
|
||||
|
355
menu/menu_thumbnail.c
Normal file
355
menu/menu_thumbnail.c
Normal file
@ -0,0 +1,355 @@
|
||||
/* Copyright (C) 2010-2019 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (menu_thumbnail.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 <features/features_cpu.h>
|
||||
#include <file/file_path.h>
|
||||
|
||||
#include "../retroarch.h"
|
||||
#include "../configuration.h"
|
||||
#include "../tasks/tasks_internal.h"
|
||||
#include "menu_animation.h"
|
||||
|
||||
#include "menu_thumbnail.h"
|
||||
|
||||
/* When streaming thumbnails, to minimise the processing
|
||||
* of unnecessary images (i.e. when scrolling rapidly through
|
||||
* playlists), we delay loading until an entry has been on screen
|
||||
* for at least menu_thumbnail_delay ms */
|
||||
#define DEFAULT_MENU_THUMBNAIL_STREAM_DELAY 83.333333f
|
||||
static float menu_thumbnail_stream_delay = DEFAULT_MENU_THUMBNAIL_STREAM_DELAY;
|
||||
|
||||
/* Duration in ms of the thumbnail 'fade in' animation */
|
||||
#define DEFAULT_MENU_THUMBNAIL_FADE_DURATION 166.66667f
|
||||
static float menu_thumbnail_fade_duration = DEFAULT_MENU_THUMBNAIL_FADE_DURATION;
|
||||
|
||||
/* Due to the asynchronous nature of thumbnail
|
||||
* loading, it is quite possible to trigger a load
|
||||
* then navigate to a different menu list before
|
||||
* the load is complete/handled. As an additional
|
||||
* safety check, we therefore tag the current menu
|
||||
* list with counter value that is incremented whenever
|
||||
* a list is cleared/set. This is sent as userdata when
|
||||
* requesting a thumbnail, and the upload is only
|
||||
* handled if the tag matches the most recent value
|
||||
* at the time when the load completes */
|
||||
static uint64_t menu_thumbnail_list_id = 0;
|
||||
|
||||
/* Utility structure, sent as userdata when pushing
|
||||
* an image load */
|
||||
typedef struct
|
||||
{
|
||||
menu_thumbnail_t *thumbnail;
|
||||
retro_time_t list_id;
|
||||
} menu_thumbnail_tag_t;
|
||||
|
||||
/* Setters */
|
||||
|
||||
/* When streaming thumbnails, sets time in ms that an
|
||||
* entry must be on screen before an image load is
|
||||
* requested */
|
||||
void menu_thumbnail_set_stream_delay(float delay)
|
||||
{
|
||||
menu_thumbnail_stream_delay = (delay >= 0.0f) ?
|
||||
delay : DEFAULT_MENU_THUMBNAIL_STREAM_DELAY;
|
||||
}
|
||||
|
||||
/* Sets duration in ms of the thumbnail 'fade in'
|
||||
* animation */
|
||||
void menu_thumbnail_set_fade_duration(float duration)
|
||||
{
|
||||
menu_thumbnail_fade_duration = (duration >= 0.0f) ?
|
||||
duration : DEFAULT_MENU_THUMBNAIL_FADE_DURATION;
|
||||
}
|
||||
|
||||
/* Getters */
|
||||
|
||||
/* Fetches current streaming thumbnails request delay */
|
||||
float menu_thumbnail_get_stream_delay(void)
|
||||
{
|
||||
return menu_thumbnail_stream_delay;
|
||||
}
|
||||
|
||||
/* Fetches current 'fade in' animation duration */
|
||||
float menu_thumbnail_get_fade_duration(void)
|
||||
{
|
||||
return menu_thumbnail_fade_duration;
|
||||
}
|
||||
|
||||
/* Callbacks */
|
||||
|
||||
/* Used to process thumbnail data following completion
|
||||
* of image load task */
|
||||
static void menu_thumbnail_handle_upload(
|
||||
retro_task_t *task, void *task_data, void *user_data, const char *err)
|
||||
{
|
||||
struct texture_image *img = (struct texture_image*)task_data;
|
||||
menu_thumbnail_tag_t *thumbnail_tag = (menu_thumbnail_tag_t*)user_data;
|
||||
menu_animation_ctx_entry_t animation_entry;
|
||||
|
||||
/* Sanity check */
|
||||
if (!thumbnail_tag)
|
||||
goto end;
|
||||
|
||||
/* Ensure that we are operating on the correct
|
||||
* thumbnail... */
|
||||
if (thumbnail_tag->list_id != menu_thumbnail_list_id)
|
||||
goto end;
|
||||
|
||||
/* Only process image if we are waiting for it */
|
||||
if (thumbnail_tag->thumbnail->status != MENU_THUMBNAIL_STATUS_PENDING)
|
||||
goto end;
|
||||
|
||||
/* Sanity check: if thumbnail already has a texture,
|
||||
* we're in some kind of weird error state - in this
|
||||
* case, the best course of action is to just reset
|
||||
* the thumbnail... */
|
||||
if (thumbnail_tag->thumbnail->texture)
|
||||
menu_thumbnail_reset(thumbnail_tag->thumbnail);
|
||||
|
||||
/* Set thumbnail 'missing' status by default
|
||||
* (saves a number of checks later) */
|
||||
thumbnail_tag->thumbnail->status = MENU_THUMBNAIL_STATUS_MISSING;
|
||||
|
||||
/* Check we have a valid image */
|
||||
if (!img)
|
||||
goto end;
|
||||
|
||||
if (img->width < 1 || img->height < 1)
|
||||
goto end;
|
||||
|
||||
/* Upload texture to GPU */
|
||||
video_driver_texture_load(
|
||||
img, TEXTURE_FILTER_MIPMAP_LINEAR, &thumbnail_tag->thumbnail->texture);
|
||||
|
||||
/* Cache dimensions */
|
||||
thumbnail_tag->thumbnail->width = img->width;
|
||||
thumbnail_tag->thumbnail->height = img->height;
|
||||
|
||||
/* Update thumbnail status */
|
||||
thumbnail_tag->thumbnail->status = MENU_THUMBNAIL_STATUS_AVAILABLE;
|
||||
|
||||
/* Trigger 'fade in' animation */
|
||||
thumbnail_tag->thumbnail->alpha = 0.0f;
|
||||
|
||||
animation_entry.easing_enum = EASING_OUT_QUAD;
|
||||
animation_entry.tag = (uintptr_t)&thumbnail_tag->thumbnail->alpha;
|
||||
animation_entry.duration = menu_thumbnail_fade_duration;
|
||||
animation_entry.target_value = 1.0f;
|
||||
animation_entry.subject = &thumbnail_tag->thumbnail->alpha;
|
||||
animation_entry.cb = NULL;
|
||||
animation_entry.userdata = NULL;
|
||||
|
||||
menu_animation_push(&animation_entry);
|
||||
|
||||
end:
|
||||
/* Clean up */
|
||||
if (img)
|
||||
{
|
||||
image_texture_free(img);
|
||||
free(img);
|
||||
}
|
||||
|
||||
if (thumbnail_tag)
|
||||
free(thumbnail_tag);
|
||||
}
|
||||
|
||||
/* Core interface */
|
||||
|
||||
/* When called, prevents the handling of any pending
|
||||
* thumbnail load requests
|
||||
* >> **MUST** be called before deleting any menu_thumbnail_t
|
||||
* objects passed to menu_thumbnail_request() or
|
||||
* menu_thumbnail_process_stream(), otherwise
|
||||
* heap-use-after-free errors *will* occur */
|
||||
void menu_thumbnail_cancel_pending_requests(void)
|
||||
{
|
||||
menu_thumbnail_list_id++;
|
||||
}
|
||||
|
||||
/* Requests loading of the specified thumbnail
|
||||
* - If operation fails, 'thumbnail->status' will be set to
|
||||
* MENU_THUMBNAIL_STATUS_MISSING
|
||||
* - If operation is successful, 'thumbnail->status' will be
|
||||
* set to MENU_THUMBNAIL_STATUS_PENDING
|
||||
* 'thumbnail' will be populated with texture info/metadata
|
||||
* once the image load is complete
|
||||
* NOTE 1: Must be called *after* menu_thumbnail_set_system()
|
||||
* and menu_thumbnail_set_content*()
|
||||
* NOTE 2: 'playlist' and 'idx' are only required here for
|
||||
* on-demand thumbnail download support
|
||||
* (an annoyance...) */
|
||||
void menu_thumbnail_request(
|
||||
menu_thumbnail_path_data_t *path_data, enum menu_thumbnail_id thumbnail_id,
|
||||
playlist_t *playlist, size_t idx, menu_thumbnail_t *thumbnail)
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
const char *thumbnail_path = NULL;
|
||||
bool has_thumbnail = false;
|
||||
|
||||
if (!path_data || !thumbnail || !settings)
|
||||
return;
|
||||
|
||||
/* Reset thumbnail, then set 'missing' status by default
|
||||
* (saves a number of checks later) */
|
||||
menu_thumbnail_reset(thumbnail);
|
||||
thumbnail->status = MENU_THUMBNAIL_STATUS_MISSING;
|
||||
|
||||
/* Update/extract thumbnail path */
|
||||
if (menu_thumbnail_is_enabled(path_data, thumbnail_id))
|
||||
if (menu_thumbnail_update_path(path_data, thumbnail_id))
|
||||
has_thumbnail = menu_thumbnail_get_path(path_data, thumbnail_id, &thumbnail_path);
|
||||
|
||||
/* Load thumbnail, if required */
|
||||
if (has_thumbnail)
|
||||
{
|
||||
if (path_is_valid(thumbnail_path))
|
||||
{
|
||||
menu_thumbnail_tag_t *thumbnail_tag =
|
||||
(menu_thumbnail_tag_t*)calloc(1, sizeof(menu_thumbnail_tag_t));
|
||||
|
||||
if (!thumbnail_tag)
|
||||
return;
|
||||
|
||||
/* Configure user data */
|
||||
thumbnail_tag->thumbnail = thumbnail;
|
||||
thumbnail_tag->list_id = menu_thumbnail_list_id;
|
||||
|
||||
/* 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, video_driver_supports_rgba(),
|
||||
settings->uints.menu_thumbnail_upscale_threshold,
|
||||
menu_thumbnail_handle_upload, thumbnail_tag))
|
||||
thumbnail->status = MENU_THUMBNAIL_STATUS_PENDING;
|
||||
}
|
||||
#ifdef HAVE_NETWORKING
|
||||
/* Handle on demand thumbnail downloads */
|
||||
else if (settings->bools.network_on_demand_thumbnails)
|
||||
{
|
||||
const char *system = NULL;
|
||||
|
||||
if (menu_thumbnail_get_system(path_data, &system))
|
||||
task_push_pl_entry_thumbnail_download(
|
||||
system, playlist_get_cached(), (unsigned)idx,
|
||||
false, true);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
/* Resets (and free()s the current texture of) the
|
||||
* specified thumbnail */
|
||||
void menu_thumbnail_reset(menu_thumbnail_t *thumbnail)
|
||||
{
|
||||
if (!thumbnail)
|
||||
return;
|
||||
|
||||
if (thumbnail->texture)
|
||||
{
|
||||
menu_animation_ctx_tag tag = (uintptr_t)&thumbnail->alpha;
|
||||
|
||||
/* Unload texture */
|
||||
video_driver_texture_unload(&thumbnail->texture);
|
||||
|
||||
/* Ensure any 'fade in' animation is killed */
|
||||
menu_animation_kill_by_tag(&tag);
|
||||
}
|
||||
|
||||
/* Reset all parameters */
|
||||
thumbnail->status = MENU_THUMBNAIL_STATUS_UNKNOWN;
|
||||
thumbnail->texture = 0;
|
||||
thumbnail->width = 0;
|
||||
thumbnail->height = 0;
|
||||
thumbnail->alpha = 0.0f;
|
||||
thumbnail->delay_timer = 0.0f;
|
||||
}
|
||||
|
||||
/* Stream processing */
|
||||
|
||||
/* Handles streaming of the specified thumbnail as it moves
|
||||
* on/off screen
|
||||
* - Must be called each frame for every on-screen entry
|
||||
* - Must be called once for each entry as it moves off-screen
|
||||
* NOTE 1: Must be called *after* menu_thumbnail_set_system()
|
||||
* NOTE 2: This function calls menu_thumbnail_set_content*()
|
||||
* > It is therefore intended for use in situations
|
||||
* where each entry has a *single* thumbnail
|
||||
* > Since I can't think of any view mode that needs
|
||||
* two thumbnails, this should be fine (i.e. we might
|
||||
* want one additional image to go with the currently
|
||||
* selected item, but this is not a streaming thing -
|
||||
* the auxiliary image can just be loaded via a normal
|
||||
* menu_thumbnail_request() */
|
||||
void menu_thumbnail_process_stream(
|
||||
menu_thumbnail_path_data_t *path_data, enum menu_thumbnail_id thumbnail_id,
|
||||
playlist_t *playlist, size_t idx, menu_thumbnail_t *thumbnail, bool on_screen)
|
||||
{
|
||||
if (!thumbnail)
|
||||
return;
|
||||
|
||||
if (on_screen)
|
||||
{
|
||||
/* Entry is on-screen
|
||||
* > Only process if current status is
|
||||
* MENU_THUMBNAIL_STATUS_UNKNOWN */
|
||||
if (thumbnail->status == MENU_THUMBNAIL_STATUS_UNKNOWN)
|
||||
{
|
||||
/* Check if stream delay timer has elapsed */
|
||||
thumbnail->delay_timer += menu_animation_get_delta_time();
|
||||
|
||||
if (thumbnail->delay_timer > menu_thumbnail_stream_delay)
|
||||
{
|
||||
/* Sanity check */
|
||||
if (!path_data || !playlist)
|
||||
return;
|
||||
|
||||
/* Update thumbnail content */
|
||||
if (!menu_thumbnail_set_content_playlist(path_data, playlist, idx))
|
||||
{
|
||||
/* Content is invalid
|
||||
* > Reset thumbnail and set missing status */
|
||||
menu_thumbnail_reset(thumbnail);
|
||||
thumbnail->status = MENU_THUMBNAIL_STATUS_MISSING;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Request image load */
|
||||
menu_thumbnail_request(
|
||||
path_data, thumbnail_id, playlist, idx, thumbnail);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Entry is off-screen
|
||||
* > If status is MENU_THUMBNAIL_STATUS_UNKNOWN,
|
||||
* thumbnail is already in a blank state - do nothing
|
||||
* In all other cases, reset thumbnail */
|
||||
if (thumbnail->status != MENU_THUMBNAIL_STATUS_UNKNOWN)
|
||||
menu_thumbnail_reset(thumbnail);
|
||||
}
|
||||
}
|
128
menu/menu_thumbnail.h
Normal file
128
menu/menu_thumbnail.h
Normal file
@ -0,0 +1,128 @@
|
||||
/* Copyright (C) 2010-2019 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (menu_thumbnail.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_H
|
||||
#define __MENU_THUMBNAIL_H
|
||||
|
||||
#include <retro_common_api.h>
|
||||
#include <libretro.h>
|
||||
|
||||
#include <boolean.h>
|
||||
|
||||
#include "menu_thumbnail_path.h"
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
/* Defines the current status of an entry
|
||||
* thumbnail texture */
|
||||
enum menu_thumbnail_status
|
||||
{
|
||||
MENU_THUMBNAIL_STATUS_UNKNOWN = 0,
|
||||
MENU_THUMBNAIL_STATUS_PENDING,
|
||||
MENU_THUMBNAIL_STATUS_AVAILABLE,
|
||||
MENU_THUMBNAIL_STATUS_MISSING
|
||||
};
|
||||
|
||||
/* Holds all runtime parameters associated with
|
||||
* an entry thumbnail */
|
||||
typedef struct
|
||||
{
|
||||
enum menu_thumbnail_status status;
|
||||
uintptr_t texture;
|
||||
unsigned width;
|
||||
unsigned height;
|
||||
float alpha;
|
||||
float delay_timer;
|
||||
} menu_thumbnail_t;
|
||||
|
||||
/* Setters */
|
||||
|
||||
/* When streaming thumbnails, sets time in ms that an
|
||||
* entry must be on screen before an image load is
|
||||
* requested */
|
||||
void menu_thumbnail_set_stream_delay(float delay);
|
||||
|
||||
/* Sets duration in ms of the thumbnail 'fade in'
|
||||
* animation */
|
||||
void menu_thumbnail_set_fade_duration(float duration);
|
||||
|
||||
/* Getters */
|
||||
|
||||
/* Fetches current streaming thumbnails request delay */
|
||||
float menu_thumbnail_get_stream_delay(void);
|
||||
|
||||
/* Fetches current 'fade in' animation duration */
|
||||
float menu_thumbnail_get_fade_duration(void);
|
||||
|
||||
/* Core interface */
|
||||
|
||||
/* When called, prevents the handling of any pending
|
||||
* thumbnail load requests
|
||||
* >> **MUST** be called before deleting any menu_thumbnail_t
|
||||
* objects passed to menu_thumbnail_request() or
|
||||
* menu_thumbnail_process_stream(), otherwise
|
||||
* heap-use-after-free errors *will* occur */
|
||||
void menu_thumbnail_cancel_pending_requests(void);
|
||||
|
||||
/* Requests loading of the specified thumbnail
|
||||
* - If operation fails, 'thumbnail->status' will be set to
|
||||
* MUI_THUMBNAIL_STATUS_MISSING
|
||||
* - If operation is successful, 'thumbnail->status' will be
|
||||
* set to MUI_THUMBNAIL_STATUS_PENDING
|
||||
* 'thumbnail' will be populated with texture info/metadata
|
||||
* once the image load is complete
|
||||
* NOTE 1: Must be called *after* menu_thumbnail_set_system()
|
||||
* and menu_thumbnail_set_content*()
|
||||
* NOTE 2: 'playlist' and 'idx' are only required here for
|
||||
* on-demand thumbnail download support
|
||||
* (an annoyance...) */
|
||||
void menu_thumbnail_request(
|
||||
menu_thumbnail_path_data_t *path_data, enum menu_thumbnail_id thumbnail_id,
|
||||
playlist_t *playlist, size_t idx, menu_thumbnail_t *thumbnail);
|
||||
|
||||
/* Resets (and free()s the current texture of) the
|
||||
* specified thumbnail */
|
||||
void menu_thumbnail_reset(menu_thumbnail_t *thumbnail);
|
||||
|
||||
/* Stream processing */
|
||||
|
||||
/* Handles streaming of the specified thumbnail as it moves
|
||||
* on/off screen
|
||||
* - Must be called each frame for every on-screen entry
|
||||
* - Must be called once for each entry as it moves off-screen
|
||||
* NOTE 1: Must be called *after* menu_thumbnail_set_system()
|
||||
* NOTE 2: This function calls menu_thumbnail_set_content*()
|
||||
* > It is therefore intended for use in situations
|
||||
* where each entry has a *single* thumbnail
|
||||
* > Since I can't think of any view mode that needs
|
||||
* two thumbnails, this should be fine (i.e. we might
|
||||
* want one additional image to go with the currently
|
||||
* selected item, but this is not a streaming thing -
|
||||
* the auxiliary image can just be loaded via a normal
|
||||
* menu_thumbnail_request() */
|
||||
void menu_thumbnail_process_stream(
|
||||
menu_thumbnail_path_data_t *path_data, enum menu_thumbnail_id thumbnail_id,
|
||||
playlist_t *playlist, size_t idx, menu_thumbnail_t *thumbnail, bool on_screen);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
@ -1,7 +1,7 @@
|
||||
/* Copyright (C) 2010-2019 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (runtime_file.c).
|
||||
* The following license statement only applies to this file (menu_thumbnail_path.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
|
@ -1,7 +1,7 @@
|
||||
/* Copyright (C) 2010-2019 The RetroArch team
|
||||
*
|
||||
* ---------------------------------------------------------------------------------------
|
||||
* The following license statement only applies to this file (runtime_file.c).
|
||||
* The following license statement only applies to this file (menu_thumbnail_path.c).
|
||||
* ---------------------------------------------------------------------------------------
|
||||
*
|
||||
* Permission is hereby granted, free of charge,
|
||||
|
12
msg_hash.h
12
msg_hash.h
@ -622,6 +622,18 @@ enum msg_hash_enums
|
||||
MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_TRANSITION_ANIM_SLIDE,
|
||||
MENU_ENUM_LABEL_VALUE_MATERIALUI_MENU_TRANSITION_ANIM_NONE,
|
||||
|
||||
MENU_LABEL(MATERIALUI_MENU_THUMBNAIL_VIEW_PORTRAIT),
|
||||
MENU_LABEL(MATERIALUI_MENU_THUMBNAIL_VIEW_LANDSCAPE),
|
||||
|
||||
MENU_ENUM_LABEL_VALUE_MATERIALUI_THUMBNAIL_VIEW_PORTRAIT_DISABLED,
|
||||
MENU_ENUM_LABEL_VALUE_MATERIALUI_THUMBNAIL_VIEW_PORTRAIT_LIST_SMALL,
|
||||
MENU_ENUM_LABEL_VALUE_MATERIALUI_THUMBNAIL_VIEW_PORTRAIT_LIST_MEDIUM,
|
||||
|
||||
MENU_ENUM_LABEL_VALUE_MATERIALUI_THUMBNAIL_VIEW_LANDSCAPE_DISABLED,
|
||||
MENU_ENUM_LABEL_VALUE_MATERIALUI_THUMBNAIL_VIEW_LANDSCAPE_LIST_SMALL,
|
||||
MENU_ENUM_LABEL_VALUE_MATERIALUI_THUMBNAIL_VIEW_LANDSCAPE_LIST_MEDIUM,
|
||||
MENU_ENUM_LABEL_VALUE_MATERIALUI_THUMBNAIL_VIEW_LANDSCAPE_LIST_LARGE,
|
||||
|
||||
MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR_LATE,
|
||||
MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR_NORMAL,
|
||||
MENU_ENUM_LABEL_VALUE_INPUT_POLL_TYPE_BEHAVIOR_EARLY,
|
||||
|
@ -474,8 +474,9 @@ static void cb_task_pl_entry_thumbnail_refresh_menu(
|
||||
bool do_refresh = false;
|
||||
playlist_t *current_playlist = playlist_get_cached();
|
||||
menu_handle_t *menu = menu_driver_get_ptr();
|
||||
settings_t *settings = config_get_ptr();
|
||||
|
||||
if (!task)
|
||||
if (!task || !settings)
|
||||
return;
|
||||
|
||||
pl_thumb = (pl_thumb_handle_t*)task->state;
|
||||
@ -487,7 +488,9 @@ static void cb_task_pl_entry_thumbnail_refresh_menu(
|
||||
* (Note: this is crude, but it's sufficient to prevent
|
||||
* 'refresh' from getting spammed when switching
|
||||
* playlists or scrolling through one playlist at
|
||||
* maximum speed with on demand downloads enabled) */
|
||||
* maximum speed with on demand downloads enabled)
|
||||
* NOTE: GLUI requires special treatment, since
|
||||
* it displays multiple thumbnails at a time... */
|
||||
|
||||
if (!current_playlist)
|
||||
return;
|
||||
@ -496,11 +499,20 @@ static void cb_task_pl_entry_thumbnail_refresh_menu(
|
||||
if (string_is_empty(playlist_get_conf_path(current_playlist)))
|
||||
return;
|
||||
|
||||
if (((pl_thumb->list_index != menu_navigation_get_selection()) &&
|
||||
(pl_thumb->list_index != menu->rpl_entry_selection_ptr)) ||
|
||||
!string_is_equal(pl_thumb->playlist_path,
|
||||
if (string_is_equal(settings->arrays.menu_driver, "glui"))
|
||||
{
|
||||
if (!string_is_equal(pl_thumb->playlist_path,
|
||||
playlist_get_conf_path(current_playlist)))
|
||||
return;
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (((pl_thumb->list_index != menu_navigation_get_selection()) &&
|
||||
(pl_thumb->list_index != menu->rpl_entry_selection_ptr)) ||
|
||||
!string_is_equal(pl_thumb->playlist_path,
|
||||
playlist_get_conf_path(current_playlist)))
|
||||
return;
|
||||
}
|
||||
|
||||
/* Only refresh if left/right thumbnails did not exist
|
||||
* when the task began, but do exist now
|
||||
@ -519,7 +531,10 @@ static void cb_task_pl_entry_thumbnail_refresh_menu(
|
||||
do_refresh = path_is_valid(left_thumbnail_path);
|
||||
|
||||
if (do_refresh)
|
||||
menu_driver_ctl(RARCH_MENU_CTL_REFRESH_THUMBNAIL_IMAGE, NULL);
|
||||
{
|
||||
unsigned i = (unsigned)pl_thumb->list_index;
|
||||
menu_driver_ctl(RARCH_MENU_CTL_REFRESH_THUMBNAIL_IMAGE, &i);
|
||||
}
|
||||
|
||||
#endif
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user