Merge pull request #10240 from natinusala/split-widgets

gfx_widgets: start moving widgets into their own file
This commit is contained in:
Twinaphex 2020-03-09 19:14:26 +01:00 committed by GitHub
commit adfef2a503
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 489 additions and 208 deletions

View File

@ -840,7 +840,8 @@ endif
OBJ += input/input_osk.o
ifeq ($(HAVE_GFX_WIDGETS), 1)
OBJ += gfx/gfx_widgets.o
OBJ += gfx/gfx_widgets.o \
gfx/widgets/gfx_widget_screenshot.o
endif
ifeq ($(HAVE_OVERLAY), 1)

View File

@ -24,6 +24,8 @@
#include "../retroarch.h"
#include "video_defines.h"
RETRO_BEGIN_DECLS
/* All coordinates and offsets are top-left oriented.

View File

@ -1,7 +1,7 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2014-2017 - Jean-André Santoni
* Copyright (C) 2015-2018 - Andre Leiradella
* Copyright (C) 2018-2019 - natinusala
* Copyright (C) 2018-2020 - natinusala
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
@ -35,7 +35,6 @@
#include "gfx_widgets.h"
#include "gfx_animation.h"
#include "gfx_display.h"
#include "font_driver.h"
@ -61,13 +60,6 @@ static float msg_queue_task_progress_2[16] = COLOR_HEX_TO_FLOAT(0x317198, 1.0f);
static float color_task_progress_bar[16] = COLOR_HEX_TO_FLOAT(0x22B14C, 1.0f);
#endif
#define TEXT_COLOR_INFO 0xD8EEFFFF
#if 0
#define TEXT_COLOR_SUCCESS 0x22B14CFF
#define TEXT_COLOR_ERROR 0xC23B22FF
#endif
#define TEXT_COLOR_FAINT 0x878787FF
static float volume_bar_background[16] = COLOR_HEX_TO_FLOAT(0x1A1A1A, 1.0f);
static float volume_bar_normal[16] = COLOR_HEX_TO_FLOAT(0x198AC6, 1.0f);
static float volume_bar_loud[16] = COLOR_HEX_TO_FLOAT(0xF5DD19, 1.0f);
@ -79,6 +71,16 @@ static uint64_t gfx_widgets_frame_count = 0;
static font_data_t *font_regular = NULL;
static font_data_t *font_bold = NULL;
font_data_t* gfx_widgets_get_font_regular()
{
return font_regular;
}
font_data_t* gfx_widgets_get_font_bold()
{
return font_bold;
}
static video_font_raster_block_t font_raster_regular;
static video_font_raster_block_t font_raster_bold;
@ -89,6 +91,11 @@ static float gfx_widgets_pure_white[16] = {
1.00, 1.00, 1.00, 1.00,
};
float* gfx_widgets_get_pure_white(void)
{
return gfx_widgets_pure_white;
}
/* FPS */
static char gfx_widgets_fps_text[255] = {0};
@ -150,6 +157,11 @@ static float gfx_widgets_backdrop_orig[16] = {
0.00, 0.00, 0.00, 0.75,
};
float* gfx_widgets_get_backdrop_orig(void)
{
return gfx_widgets_backdrop_orig;
}
static float gfx_widgets_backdrop[16] = {
0.00, 0.00, 0.00, 0.75,
0.00, 0.00, 0.00, 0.75,
@ -216,8 +228,12 @@ static uintptr_t msg_queue_icon_outline = 0;
static uintptr_t msg_queue_icon_rect = 0;
static bool msg_queue_has_icons = false;
extern gfx_animation_ctx_tag
gfx_widgets_generic_tag;
extern gfx_animation_ctx_tag gfx_widgets_generic_tag;
gfx_animation_ctx_tag gfx_widgets_get_generic_tag(void)
{
return gfx_widgets_generic_tag;
}
/* There can only be one message animation at a time to
* avoid confusing users */
@ -279,25 +295,6 @@ static gfx_animation_ctx_tag volume_tag = (uintptr_t) &volume_alpha;
static bool volume_mute = false;
/* Screenshot */
static float screenshot_alpha = 0.0f;
static uintptr_t screenshot_texture = 0;
static unsigned screenshot_texture_width = 0;
static unsigned screenshot_texture_height = 0;
static char screenshot_shotname[256] = {0};
static char screenshot_filename[256] = {0};
static bool screenshot_loaded = false;
static float screenshot_scale_factor = 0.0f;
static float screenshot_y = 0.0f;
static unsigned screenshot_height = 0;
static unsigned screenshot_width = 0;
static unsigned screenshot_thumbnail_width = 0;
static unsigned screenshot_thumbnail_height = 0;
static gfx_timer_t screenshot_timer;
static unsigned screenshot_shotname_length = 0;
#ifdef HAVE_TRANSLATE
/* AI Service Overlay */
static int ai_service_overlay_state = 0;
@ -325,10 +322,30 @@ static float last_scale_factor = 0.0f;
static float msg_queue_text_scale_factor = 0.0f;
static float widget_font_size = 0.0f;
float gfx_widgets_get_font_size(void)
{
return widget_font_size;
}
static unsigned simple_widget_padding = 0;
static unsigned simple_widget_height = 0;
static unsigned glyph_width = 0;
unsigned gfx_widgets_get_padding(void)
{
return simple_widget_padding;
}
unsigned gfx_widgets_get_height(void)
{
return simple_widget_height;
}
unsigned gfx_widgets_get_glyph_width(void)
{
return glyph_width;
}
static unsigned libretro_message_width = 0;
static unsigned msg_queue_height;
@ -361,6 +378,13 @@ static unsigned divider_width_1px = 1;
static unsigned last_video_width = 0;
static unsigned last_video_height = 0;
/* Widgets list */
const static gfx_widget_t* const widgets[] = {
&gfx_widget_screenshot
};
static const size_t widgets_len = sizeof(widgets) / sizeof(widgets[0]);
static void msg_widget_msg_transition_animation_done(void *userdata)
{
menu_widget_msg_t *msg = (menu_widget_msg_t*)userdata;
@ -734,7 +758,7 @@ static void gfx_widgets_msg_queue_kill(unsigned idx)
gfx_widgets_msg_queue_move();
}
static void gfx_widgets_draw_icon(
void gfx_widgets_draw_icon(
void *userdata,
unsigned video_width,
unsigned video_height,
@ -838,7 +862,7 @@ static void gfx_widgets_draw_icon_blend(
}
#endif
static float gfx_widgets_get_thumbnail_scale_factor(
float gfx_widgets_get_thumbnail_scale_factor(
const float dst_width, const float dst_height,
const float image_width, const float image_height)
{
@ -850,28 +874,6 @@ static float gfx_widgets_get_thumbnail_scale_factor(
return (dst_width / image_width);
}
static void gfx_widgets_screenshot_dispose(void *userdata)
{
screenshot_loaded = false;
video_driver_texture_unload(&screenshot_texture);
screenshot_texture = 0;
}
static void gfx_widgets_screenshot_end(void *userdata)
{
gfx_animation_ctx_entry_t entry;
entry.cb = gfx_widgets_screenshot_dispose;
entry.duration = MSG_QUEUE_ANIMATION_DURATION;
entry.easing_enum = EASING_OUT_QUAD;
entry.subject = &screenshot_y;
entry.tag = gfx_widgets_generic_tag;
entry.target_value = -((float)screenshot_height);
entry.userdata = NULL;
gfx_animation_push(&entry);
}
static void gfx_widgets_start_msg_expiration_timer(menu_widget_msg_t *msg_widget, unsigned duration)
{
gfx_timer_ctx_entry_t timer;
@ -955,10 +957,18 @@ void gfx_widgets_iterate(
video_driver_monitor_reset();
}
for (i = 0; i < widgets_len; i++)
{
const gfx_widget_t* widget = widgets[i];
if (widget->iterate)
widget->iterate(width, height, fullscreen, dir_assets, font_path, is_threaded);
}
/* Messages queue */
/* Consume one message if available */
if ((fifo_read_avail(msg_queue) > 0)
if ((fifo_read_avail(msg_queue) > 0)
&& !widgets_moving
&& (current_msgs->size < MSG_QUEUE_ONSCREEN_MAX))
{
@ -1032,44 +1042,6 @@ void gfx_widgets_iterate(
break;
}
}
/* Load screenshot and start its animation */
if (screenshot_filename[0] != '\0')
{
gfx_timer_ctx_entry_t timer;
video_driver_texture_unload(&screenshot_texture);
screenshot_texture = 0;
gfx_display_reset_textures_list(screenshot_filename,
"", &screenshot_texture, TEXTURE_FILTER_MIPMAP_LINEAR,
&screenshot_texture_width, &screenshot_texture_height);
screenshot_height = widget_font_size * 4;
screenshot_width = width;
screenshot_scale_factor = gfx_widgets_get_thumbnail_scale_factor(
width, screenshot_height,
screenshot_texture_width, screenshot_texture_height
);
screenshot_thumbnail_width = screenshot_texture_width * screenshot_scale_factor;
screenshot_thumbnail_height = screenshot_texture_height * screenshot_scale_factor;
screenshot_shotname_length = (width - screenshot_thumbnail_width - simple_widget_padding*2) / glyph_width;
screenshot_y = 0.0f;
timer.cb = gfx_widgets_screenshot_end;
timer.duration = SCREENSHOT_NOTIFICATION_DURATION;
timer.userdata = NULL;
gfx_timer_start(&screenshot_timer, &timer);
screenshot_loaded = true;
screenshot_filename[0] = '\0';
}
}
static int gfx_widgets_draw_indicator(
@ -1630,62 +1602,6 @@ void gfx_widgets_frame(void *data)
1, false, 0, false);
}
/* Screenshot */
if (screenshot_loaded)
{
char shotname[256];
gfx_animation_ctx_ticker_t ticker;
gfx_display_set_alpha(gfx_widgets_backdrop_orig, DEFAULT_BACKDROP);
gfx_display_draw_quad(userdata,
video_width, video_height,
0, screenshot_y,
screenshot_width, screenshot_height,
video_width, video_height,
gfx_widgets_backdrop_orig
);
gfx_display_set_alpha(gfx_widgets_pure_white, 1.0f);
gfx_widgets_draw_icon(
userdata,
video_width,
video_height,
screenshot_thumbnail_width,
screenshot_thumbnail_height,
screenshot_texture,
0, screenshot_y,
video_width, video_height,
0, 1, gfx_widgets_pure_white
);
gfx_display_draw_text(font_regular,
msg_hash_to_str(MSG_SCREENSHOT_SAVED),
screenshot_thumbnail_width + simple_widget_padding, widget_font_size * 1.9f + screenshot_y,
video_width, video_height,
TEXT_COLOR_FAINT,
TEXT_ALIGN_LEFT,
1, false, 0, true
);
ticker.idx = gfx_animation_get_ticker_idx();
ticker.len = screenshot_shotname_length;
ticker.s = shotname;
ticker.selected = true;
ticker.str = screenshot_shotname;
gfx_animation_ticker(&ticker);
gfx_display_draw_text(font_regular,
shotname,
screenshot_thumbnail_width + simple_widget_padding, widget_font_size * 2.9f + screenshot_y,
video_width, video_height,
TEXT_COLOR_INFO,
TEXT_ALIGN_LEFT,
1, false, 0, true
);
}
#ifdef HAVE_CHEEVOS
/* Achievement notification */
if (cheevo_popup_queue_read_index >= 0 && cheevo_popup_queue[cheevo_popup_queue_read_index].title)
@ -2032,18 +1948,12 @@ void gfx_widgets_frame(void *data)
gfx_widgets_icons_textures[MENU_WIDGETS_ICON_SLOW_MOTION], (fps_show ? simple_widget_height : 0), top_right_x_advance,
MSG_SLOW_MOTION);
/* Screenshot */
if (screenshot_alpha > 0.0f)
for (i = 0; i < widgets_len; i++)
{
gfx_display_set_alpha(gfx_widgets_pure_white, screenshot_alpha);
gfx_display_draw_quad(userdata,
video_width,
video_height,
0, 0,
video_width, video_height,
video_width, video_height,
gfx_widgets_pure_white
);
const gfx_widget_t* widget = widgets[i];
if (widget->frame)
widget->frame(data);
}
#ifdef HAVE_MENU
@ -2066,11 +1976,21 @@ void gfx_widgets_frame(void *data)
bool gfx_widgets_init(bool video_is_threaded, bool fullscreen)
{
size_t i;
if (!gfx_display_init_first_driver(video_is_threaded))
goto error;
gfx_widgets_frame_count = 0;
for (i = 0; i < widgets_len; i++)
{
const gfx_widget_t* widget = widgets[i];
if (widget->init)
widget->init(video_is_threaded, fullscreen);
}
msg_queue = fifo_new(MSG_QUEUE_PENDING_MAX * sizeof(menu_widget_msg_t*));
if (!msg_queue)
@ -2103,6 +2023,7 @@ error:
static void gfx_widgets_layout(
bool is_threaded, const char *dir_assets, char *font_path)
{
size_t i;
int font_height = 0;
/* Base font size must be determined first
@ -2225,13 +2146,21 @@ static void gfx_widgets_layout(
divider_width_1px = 1;
if (last_scale_factor > 1.0f)
divider_width_1px = (unsigned)(last_scale_factor + 0.5f);
for (i = 0; i < widgets_len; i++)
{
const gfx_widget_t* widget = widgets[i];
if (widget->layout)
widget->layout(is_threaded, dir_assets, font_path);
}
}
void gfx_widgets_context_reset(bool is_threaded,
unsigned width, unsigned height, bool fullscreen,
const char *dir_assets, char *font_path)
{
int i;
size_t i;
char xmb_path[PATH_MAX_LENGTH];
char monochrome_png_path[PATH_MAX_LENGTH];
char gfx_widgets_path[PATH_MAX_LENGTH];
@ -2286,6 +2215,14 @@ void gfx_widgets_context_reset(bool is_threaded,
msg_queue_has_icons = msg_queue_icon && msg_queue_icon_outline && msg_queue_icon_rect;
for (i = 0; i < widgets_len; i++)
{
const gfx_widget_t* widget = widgets[i];
if (widget->context_reset)
widget->context_reset(is_threaded, width, height, fullscreen, dir_assets, font_path);
}
/* Update scaling/dimensions */
last_video_width = width;
last_video_height = height;
@ -2299,7 +2236,15 @@ void gfx_widgets_context_reset(bool is_threaded,
static void gfx_widgets_context_destroy(void)
{
unsigned i;
size_t i;
for (i = 0; i < widgets_len; i++)
{
const gfx_widget_t* widget = widgets[i];
if (widget->context_destroy)
widget->context_destroy();
}
/* TODO: Dismiss onscreen notifications that have been freed */
@ -2364,6 +2309,14 @@ void gfx_widgets_free(void)
gfx_widgets_context_destroy();
for (i = 0; i < widgets_len; i++)
{
const gfx_widget_t* widget = widgets[i];
if (widget->free)
widget->free();
}
/* Kill any pending animation */
gfx_animation_kill_by_tag(&volume_tag);
gfx_animation_kill_by_tag(&gfx_widgets_generic_tag);
@ -2435,10 +2388,6 @@ void gfx_widgets_free(void)
/* Volume */
volume_alpha = 0.0f;
/* Screenshot */
screenshot_alpha = 0.0f;
gfx_widgets_screenshot_dispose(NULL);
}
static void gfx_widgets_volume_timer_end(void *userdata)
@ -2527,43 +2476,6 @@ void gfx_widgets_ai_service_overlay_unload(void)
}
#endif
static void gfx_widgets_screenshot_fadeout(void *userdata)
{
gfx_animation_ctx_entry_t entry;
entry.cb = NULL;
entry.duration = SCREENSHOT_DURATION_OUT;
entry.easing_enum = EASING_OUT_QUAD;
entry.subject = &screenshot_alpha;
entry.tag = gfx_widgets_generic_tag;
entry.target_value = 0.0f;
entry.userdata = NULL;
gfx_animation_push(&entry);
}
static void gfx_widgets_play_screenshot_flash(void)
{
gfx_animation_ctx_entry_t entry;
entry.cb = gfx_widgets_screenshot_fadeout;
entry.duration = SCREENSHOT_DURATION_IN;
entry.easing_enum = EASING_IN_QUAD;
entry.subject = &screenshot_alpha;
entry.tag = gfx_widgets_generic_tag;
entry.target_value = 1.0f;
entry.userdata = NULL;
gfx_animation_push(&entry);
}
void gfx_widgets_screenshot_taken(const char *shotname, const char *filename)
{
gfx_widgets_play_screenshot_flash();
strlcpy(screenshot_filename, filename, sizeof(screenshot_filename));
strlcpy(screenshot_shotname, shotname, sizeof(screenshot_shotname));
}
static void gfx_widgets_end_load_content_animation(void *userdata)
{
#if 0
@ -2870,7 +2782,7 @@ void gfx_widgets_set_libretro_message(const char *msg, unsigned duration)
gfx_animation_ctx_tag tag = (uintptr_t) &libretro_message_timer;
strlcpy(libretro_message, msg, sizeof(libretro_message));
libretro_message_alpha = DEFAULT_BACKDROP;
/* Kill and restart the timer / animation */

View File

@ -24,6 +24,8 @@
#include <queues/task_queue.h>
#include <queues/message_queue.h>
#include "gfx_animation.h"
#define DEFAULT_BACKDROP 0.75f
#define MSG_QUEUE_PENDING_MAX 32
@ -31,15 +33,88 @@
#define MSG_QUEUE_ANIMATION_DURATION 330
#define VOLUME_DURATION 3000
#define SCREENSHOT_DURATION_IN 66
#define SCREENSHOT_DURATION_OUT SCREENSHOT_DURATION_IN*10
#define SCREENSHOT_NOTIFICATION_DURATION 6000
#define CHEEVO_NOTIFICATION_DURATION 4000
#define TASK_FINISHED_DURATION 3000
#define HOURGLASS_INTERVAL 5000
#define HOURGLASS_DURATION 1000
#define GENERIC_MESSAGE_DURATION 3000
#define TEXT_COLOR_INFO 0xD8EEFFFF
#if 0
#define TEXT_COLOR_SUCCESS 0x22B14CFF
#define TEXT_COLOR_ERROR 0xC23B22FF
#endif
#define TEXT_COLOR_FAINT 0x878787FF
/* A widget */
/* TODO: cleanup all unused parameters */
struct gfx_widget
{
/* called when the widgets system is initialized
* -> initialize the widget here */
bool (*init)(bool video_is_threaded, bool fullscreen);
/* called when the widgets system is freed
* -> free the widget here */
void (*free)(void);
/* called when the graphics context is reset
* -> (re)load the textures here */
void (*context_reset)(bool is_threaded,
unsigned width, unsigned height, bool fullscreen,
const char *dir_assets, char *font_path);
/* called when the graphics context is destroyed
* -> release the textures here */
void (*context_destroy)(void);
/* called when the window resolution changes
* -> (re)layout the widget here */
void (*layout)(bool is_threaded, const char *dir_assets, char *font_path);
/* called every frame on the main thread
* -> update the widget logic here */
void (*iterate)(
unsigned width, unsigned height, bool fullscreen,
const char *dir_assets, char *font_path,
bool is_threaded);
/* called every frame
* (on the video thread if threaded video is on)
* -> draw the widget here */
void (*frame)(void* data);
};
gfx_animation_ctx_tag gfx_widgets_get_generic_tag(void);
float* gfx_widgets_get_pure_white(void);
unsigned gfx_widgets_get_padding(void);
unsigned gfx_widgets_get_height(void);
unsigned gfx_widgets_get_glyph_width(void);
float gfx_widgets_get_font_size(void);
font_data_t* gfx_widgets_get_font_regular(void);
font_data_t* gfx_widgets_get_font_bold(void);
float* gfx_widgets_get_backdrop_orig(void);
float gfx_widgets_get_thumbnail_scale_factor(
const float dst_width, const float dst_height,
const float image_width, const float image_height);
void gfx_widgets_draw_icon(
void *userdata,
unsigned video_width,
unsigned video_height,
unsigned icon_width,
unsigned icon_height,
uintptr_t texture,
float x, float y,
unsigned width, unsigned height,
float rotation, float scale_factor,
float *color);
typedef struct gfx_widget gfx_widget_t;
extern const gfx_widget_t gfx_widget_screenshot;
bool gfx_widgets_init(bool video_is_threaded, bool fullscreen);
void gfx_widgets_free(void);

View File

@ -0,0 +1,290 @@
/* RetroArch - A frontend for libretro.
* Copyright (C) 2014-2017 - Jean-André Santoni
* Copyright (C) 2015-2018 - Andre Leiradella
* Copyright (C) 2018-2020 - natinusala
*
* RetroArch is free software: you can redistribute it and/or modify it under the terms
* of the GNU General Public License as published by the Free Software Found-
* ation, either version 3 of the License, or (at your option) any later version.
*
* RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
* without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along with RetroArch.
* If not, see <http://www.gnu.org/licenses/>.
*/
#include "../gfx_widgets.h"
#include "../gfx_animation.h"
#include "../gfx_display.h"
#include "../../retroarch.h"
#define SCREENSHOT_DURATION_IN 66
#define SCREENSHOT_DURATION_OUT SCREENSHOT_DURATION_IN*10
#define SCREENSHOT_NOTIFICATION_DURATION 6000
struct gfx_widget_screenshot_state
{
float alpha;
uintptr_t texture;
unsigned texture_width;
unsigned texture_height;
char shotname[256];
char filename[256];
bool loaded;
float scale_factor;
float y;
unsigned height;
unsigned width;
unsigned thumbnail_width;
unsigned thumbnail_height;
gfx_timer_t timer;
unsigned shotname_length;
};
typedef struct gfx_widget_screenshot_state gfx_widget_screenshot_state_t;
static gfx_widget_screenshot_state_t p_state = {
0.0f,
0,
0,
0,
{0},
{0},
false,
0.0f,
0.0f,
0,
0,
0,
0,
0.0f,
0
};
static gfx_widget_screenshot_state_t* gfx_widget_screenshot_get_ptr(void)
{
return &p_state;
}
static void gfx_widgets_screenshot_fadeout(void *userdata)
{
gfx_widget_screenshot_state_t* state = gfx_widget_screenshot_get_ptr();
gfx_animation_ctx_entry_t entry;
entry.cb = NULL;
entry.duration = SCREENSHOT_DURATION_OUT;
entry.easing_enum = EASING_OUT_QUAD;
entry.subject = &state->alpha;
entry.tag = gfx_widgets_get_generic_tag();
entry.target_value = 0.0f;
entry.userdata = NULL;
gfx_animation_push(&entry);
}
static void gfx_widgets_play_screenshot_flash(void)
{
gfx_widget_screenshot_state_t* state = gfx_widget_screenshot_get_ptr();
gfx_animation_ctx_entry_t entry;
entry.cb = gfx_widgets_screenshot_fadeout;
entry.duration = SCREENSHOT_DURATION_IN;
entry.easing_enum = EASING_IN_QUAD;
entry.subject = &state->alpha;
entry.tag = gfx_widgets_get_generic_tag();
entry.target_value = 1.0f;
entry.userdata = NULL;
gfx_animation_push(&entry);
}
void gfx_widgets_screenshot_taken(const char *shotname, const char *filename)
{
gfx_widget_screenshot_state_t* state = gfx_widget_screenshot_get_ptr();
gfx_widgets_play_screenshot_flash();
strlcpy(state->filename, filename, sizeof(state->filename));
strlcpy(state->shotname, shotname, sizeof(state->shotname));
}
static void gfx_widgets_screenshot_dispose(void *userdata)
{
gfx_widget_screenshot_state_t* state = gfx_widget_screenshot_get_ptr();
state->loaded = false;
video_driver_texture_unload(&state->texture);
state->texture = 0;
}
static void gfx_widgets_screenshot_end(void *userdata)
{
gfx_widget_screenshot_state_t* state = gfx_widget_screenshot_get_ptr();
gfx_animation_ctx_entry_t entry;
entry.cb = gfx_widgets_screenshot_dispose;
entry.duration = MSG_QUEUE_ANIMATION_DURATION;
entry.easing_enum = EASING_OUT_QUAD;
entry.subject = &state->y;
entry.tag = gfx_widgets_get_generic_tag();
entry.target_value = -((float)state->height);
entry.userdata = NULL;
gfx_animation_push(&entry);
}
static void gfx_widget_screenshot_free(void)
{
gfx_widget_screenshot_state_t* state = gfx_widget_screenshot_get_ptr();
state->alpha = 0.0f;
gfx_widgets_screenshot_dispose(NULL);
}
static void gfx_widget_screenshot_frame(void* data)
{
video_frame_info_t *video_info = (video_frame_info_t*)data;
void *userdata = video_info->userdata;
unsigned video_width = video_info->width;
unsigned video_height = video_info->height;
unsigned padding = gfx_widgets_get_padding();
float font_size = gfx_widgets_get_font_size();
font_data_t* font_regular = gfx_widgets_get_font_regular();
float* pure_white = gfx_widgets_get_pure_white();
gfx_widget_screenshot_state_t* state = gfx_widget_screenshot_get_ptr();
/* Screenshot */
if (state->loaded)
{
char shotname[256];
gfx_animation_ctx_ticker_t ticker;
gfx_display_set_alpha(gfx_widgets_get_backdrop_orig(), DEFAULT_BACKDROP);
gfx_display_draw_quad(userdata,
video_width, video_height,
0, state->y,
state->width, state->height,
video_width, video_height,
gfx_widgets_get_backdrop_orig()
);
gfx_display_set_alpha(pure_white, 1.0f);
gfx_widgets_draw_icon(
userdata,
video_width,
video_height,
state->thumbnail_width,
state->thumbnail_height,
state->texture,
0, state->y,
video_width, video_height,
0, 1, pure_white
);
gfx_display_draw_text(font_regular,
msg_hash_to_str(MSG_SCREENSHOT_SAVED),
state->thumbnail_width + padding, font_size * 1.9f + state->y,
video_width, video_height,
TEXT_COLOR_FAINT,
TEXT_ALIGN_LEFT,
1, false, 0, true
);
ticker.idx = gfx_animation_get_ticker_idx();
ticker.len = state->shotname_length;
ticker.s = shotname;
ticker.selected = true;
ticker.str = state->shotname;
gfx_animation_ticker(&ticker);
gfx_display_draw_text(font_regular,
shotname,
state->thumbnail_width + padding, font_size * 2.9f + state->y,
video_width, video_height,
TEXT_COLOR_INFO,
TEXT_ALIGN_LEFT,
1, false, 0, true
);
}
/* Flash effect */
if (state->alpha > 0.0f)
{
gfx_display_set_alpha(pure_white, state->alpha);
gfx_display_draw_quad(userdata,
video_width,
video_height,
0, 0,
video_width, video_height,
video_width, video_height,
pure_white
);
}
}
static void gfx_widget_screenshot_iterate(unsigned width, unsigned height, bool fullscreen,
const char *dir_assets, char *font_path,
bool is_threaded)
{
gfx_widget_screenshot_state_t* state = gfx_widget_screenshot_get_ptr();
float font_size = gfx_widgets_get_font_size();
unsigned padding = gfx_widgets_get_padding();
unsigned glyph_width = gfx_widgets_get_glyph_width();
/* Load screenshot and start its animation */
if (state->filename[0] != '\0')
{
gfx_timer_ctx_entry_t timer;
video_driver_texture_unload(&state->texture);
state->texture = 0;
gfx_display_reset_textures_list(state->filename,
"", &state->texture, TEXTURE_FILTER_MIPMAP_LINEAR,
&state->texture_width, &state->texture_height);
state->height = font_size * 4;
state->width = width;
state->scale_factor = gfx_widgets_get_thumbnail_scale_factor(
width, state->height,
state->texture_width, state->texture_height
);
state->thumbnail_width = state->texture_width * state->scale_factor;
state->thumbnail_height = state->texture_height * state->scale_factor;
state->shotname_length = (width - state->thumbnail_width - padding*2) / glyph_width;
state->y = 0.0f;
timer.cb = gfx_widgets_screenshot_end;
timer.duration = SCREENSHOT_NOTIFICATION_DURATION;
timer.userdata = NULL;
gfx_timer_start(&state->timer, &timer);
state->loaded = true;
state->filename[0] = '\0';
}
}
const gfx_widget_t gfx_widget_screenshot = {
NULL, /* init */
gfx_widget_screenshot_free,
NULL, /* context_reset*/
NULL, /* context_destroy */
NULL, /* layout */
gfx_widget_screenshot_iterate,
gfx_widget_screenshot_frame
};

View File

@ -1261,6 +1261,7 @@ MENU
#ifdef HAVE_GFX_WIDGETS
#include "../gfx/gfx_widgets.c"
#include "../gfx/widgets/gfx_widget_screenshot.c"
#endif
#include "../input/input_osk.c"