mirror of
https://github.com/libretro/RetroArch
synced 2025-01-31 06:32:48 +00:00
Merge pull request #9485 from jdgleaver/input-update
Overhaul menu mouse/touchscreen input handling
This commit is contained in:
commit
36e5909057
@ -143,6 +143,7 @@ enum
|
||||
typedef struct materialui_handle
|
||||
{
|
||||
bool need_compute;
|
||||
bool need_scroll;
|
||||
bool mouse_show;
|
||||
|
||||
int cursor_size;
|
||||
@ -645,6 +646,40 @@ static void materialui_compute_entries_box(materialui_handle_t* mui, int width,
|
||||
mui->content_height = sum;
|
||||
}
|
||||
|
||||
/* Compute the scroll value depending on the highlighted entry */
|
||||
static float materialui_get_scroll(materialui_handle_t *mui)
|
||||
{
|
||||
unsigned i, width, height = 0;
|
||||
float half, sum = 0;
|
||||
size_t selection = menu_navigation_get_selection();
|
||||
file_list_t *list = menu_entries_get_selection_buf_ptr(0);
|
||||
|
||||
if (!mui)
|
||||
return 0;
|
||||
|
||||
/* Whenever we perform a 'manual' scroll, scroll
|
||||
* acceleration must be reset */
|
||||
menu_input_set_pointer_y_accel(0.0f);
|
||||
|
||||
video_driver_get_size(&width, &height);
|
||||
|
||||
half = height / 2;
|
||||
|
||||
for (i = 0; i < selection; i++)
|
||||
{
|
||||
materialui_node_t *node = (materialui_node_t*)
|
||||
file_list_get_userdata_at_offset(list, i);
|
||||
|
||||
if (node)
|
||||
sum += node->line_height;
|
||||
}
|
||||
|
||||
if (sum < half)
|
||||
return 0;
|
||||
|
||||
return sum - half;
|
||||
}
|
||||
|
||||
/* Called on each frame. We use this callback to implement the touch scroll
|
||||
with acceleration */
|
||||
static void materialui_render(void *data,
|
||||
@ -652,6 +687,7 @@ static void materialui_render(void *data,
|
||||
bool is_idle)
|
||||
{
|
||||
unsigned bottom, header_height;
|
||||
menu_input_pointer_t pointer;
|
||||
size_t i = 0;
|
||||
materialui_handle_t *mui = (materialui_handle_t*)data;
|
||||
settings_t *settings = config_get_ptr();
|
||||
@ -660,61 +696,63 @@ static void materialui_render(void *data,
|
||||
if (!mui)
|
||||
return;
|
||||
|
||||
/* Here's a nasty issue:
|
||||
* After calling populate_entries(), we need to call
|
||||
* materialui_get_scroll() so the last selected item
|
||||
* is correctly displayed on screen.
|
||||
* But we can't do this until materialui_compute_entries_box()
|
||||
* has been called, so we should delegate it until mui->need_compute
|
||||
* is acted upon.
|
||||
* *But* we can't do this in the same frame that mui->need_compute
|
||||
* is acted upon, because of the order in which materialui_frame()
|
||||
* and materialui_render() are called. Since mui->tabs_height is
|
||||
* set by materialui_frame(), the first time materialui_render() is
|
||||
* called after populate_entries() it has the wrong mui->tabs_height
|
||||
* value...
|
||||
* We therefore have to delegate the scroll until the frame after
|
||||
* mui->need_compute is handled... */
|
||||
if (mui->need_scroll)
|
||||
{
|
||||
mui->scroll_y = materialui_get_scroll(mui);
|
||||
mui->need_scroll = false;
|
||||
}
|
||||
|
||||
if (mui->need_compute)
|
||||
{
|
||||
if (mui->font)
|
||||
materialui_compute_entries_box(mui, width, height);
|
||||
mui->need_compute = false;
|
||||
mui->need_scroll = true;
|
||||
}
|
||||
|
||||
menu_display_set_width(width);
|
||||
menu_display_set_height(height);
|
||||
header_height = menu_display_get_header_height();
|
||||
|
||||
if (settings->bools.menu_pointer_enable)
|
||||
menu_input_get_pointer_state(&pointer);
|
||||
|
||||
if (pointer.type != MENU_POINTER_DISABLED)
|
||||
{
|
||||
size_t ii;
|
||||
int16_t pointer_y = menu_input_pointer_state(MENU_POINTER_Y_AXIS);
|
||||
float old_accel_val = 0.0f;
|
||||
float new_accel_val = 0.0f;
|
||||
size_t entries_end = menu_entries_get_size();
|
||||
int16_t pointer_y = pointer.y;
|
||||
float old_accel_val = 0.0f;
|
||||
float new_accel_val = 0.0f;
|
||||
size_t entries_end = menu_entries_get_size();
|
||||
|
||||
for (ii = 0; ii < entries_end; ii++)
|
||||
{
|
||||
materialui_node_t *node = (materialui_node_t*)
|
||||
file_list_get_userdata_at_offset(list, ii);
|
||||
|
||||
if (pointer_y > (-mui->scroll_y + header_height + node->y)
|
||||
&& pointer_y < (-mui->scroll_y + header_height + node->y + node->line_height)
|
||||
)
|
||||
menu_input_ctl(MENU_INPUT_CTL_POINTER_PTR, &ii);
|
||||
if ((pointer_y > (-mui->scroll_y + header_height + node->y)) &&
|
||||
(pointer_y < (-mui->scroll_y + header_height + node->y + node->line_height)))
|
||||
{
|
||||
menu_input_set_pointer_selection(ii);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
menu_input_ctl(MENU_INPUT_CTL_POINTER_ACCEL_READ, &old_accel_val);
|
||||
|
||||
mui->scroll_y -= old_accel_val;
|
||||
|
||||
new_accel_val = old_accel_val * 0.96;
|
||||
|
||||
menu_input_ctl(MENU_INPUT_CTL_POINTER_ACCEL_WRITE, &new_accel_val);
|
||||
}
|
||||
|
||||
if (settings->bools.menu_mouse_enable)
|
||||
{
|
||||
size_t ii;
|
||||
int16_t mouse_y = menu_input_mouse_state(MENU_MOUSE_Y_AXIS);
|
||||
size_t entries_end = menu_entries_get_size();
|
||||
|
||||
for (ii = 0; ii < entries_end; ii++)
|
||||
{
|
||||
materialui_node_t *node = (materialui_node_t*)
|
||||
file_list_get_userdata_at_offset(list, ii);
|
||||
|
||||
if (mouse_y > (-mui->scroll_y + header_height + node->y)
|
||||
&& mouse_y < (-mui->scroll_y + header_height + node->y + node->line_height)
|
||||
)
|
||||
menu_input_ctl(MENU_INPUT_CTL_MOUSE_PTR, &ii);
|
||||
}
|
||||
mui->scroll_y -= pointer.y_accel;
|
||||
}
|
||||
|
||||
if (mui->scroll_y < 0)
|
||||
@ -1664,15 +1702,20 @@ static void materialui_frame(void *data, video_frame_info_t *video_info)
|
||||
}
|
||||
|
||||
if (mui->mouse_show)
|
||||
{
|
||||
menu_input_pointer_t pointer;
|
||||
menu_input_get_pointer_state(&pointer);
|
||||
|
||||
menu_display_draw_cursor(
|
||||
video_info,
|
||||
&white_bg[0],
|
||||
mui->cursor_size,
|
||||
mui->textures.list[MUI_TEXTURE_POINTER],
|
||||
menu_input_mouse_state(MENU_MOUSE_X_AXIS),
|
||||
menu_input_mouse_state(MENU_MOUSE_Y_AXIS),
|
||||
pointer.x,
|
||||
pointer.y,
|
||||
width,
|
||||
height);
|
||||
}
|
||||
|
||||
menu_display_restore_clear_color();
|
||||
menu_display_unset_viewport(video_info->width, video_info->height);
|
||||
@ -1766,6 +1809,7 @@ static void *materialui_init(void **userdata, bool video_is_threaded)
|
||||
*userdata = mui;
|
||||
mui->cursor_size = scale_factor / 3;
|
||||
mui->need_compute = false;
|
||||
mui->need_scroll = false;
|
||||
|
||||
mui->menu_title[0] = '\0';
|
||||
|
||||
@ -1840,36 +1884,6 @@ static bool materialui_load_image(void *userdata, void *data, enum menu_image_ty
|
||||
return true;
|
||||
}
|
||||
|
||||
/* Compute the scroll value depending on the highlighted entry */
|
||||
static float materialui_get_scroll(materialui_handle_t *mui)
|
||||
{
|
||||
unsigned i, width, height = 0;
|
||||
float half, sum = 0;
|
||||
size_t selection = menu_navigation_get_selection();
|
||||
file_list_t *list = menu_entries_get_selection_buf_ptr(0);
|
||||
|
||||
if (!mui)
|
||||
return 0;
|
||||
|
||||
video_driver_get_size(&width, &height);
|
||||
|
||||
half = height / 2;
|
||||
|
||||
for (i = 0; i < selection; i++)
|
||||
{
|
||||
materialui_node_t *node = (materialui_node_t*)
|
||||
file_list_get_userdata_at_offset(list, i);
|
||||
|
||||
if (node)
|
||||
sum += node->line_height;
|
||||
}
|
||||
|
||||
if (sum < half)
|
||||
return 0;
|
||||
|
||||
return sum - half;
|
||||
}
|
||||
|
||||
/* The navigation pointer has been updated (for example by pressing up or down
|
||||
on the keyboard). We use this function to animate the scroll. */
|
||||
static void materialui_navigation_set(void *data, bool scroll)
|
||||
@ -1881,6 +1895,11 @@ static void materialui_navigation_set(void *data, bool scroll)
|
||||
if (!mui || !scroll)
|
||||
return;
|
||||
|
||||
/* mui->scroll_y will be modified by the animation
|
||||
* - Set scroll acceleration to zero to minimise
|
||||
* potential conflicts */
|
||||
menu_input_set_pointer_y_accel(0.0f);
|
||||
|
||||
entry.duration = 166;
|
||||
entry.target_value = scroll_pos;
|
||||
entry.subject = &mui->scroll_y;
|
||||
@ -1895,7 +1914,11 @@ static void materialui_navigation_set(void *data, bool scroll)
|
||||
|
||||
static void materialui_list_set_selection(void *data, file_list_t *list)
|
||||
{
|
||||
materialui_navigation_set(data, true);
|
||||
/* This is called upon MENU_ACTION_CANCEL
|
||||
* Have to set 'scroll' to false, otherwise
|
||||
* navigating backwards in the menu is absolutely
|
||||
* horrendous... */
|
||||
materialui_navigation_set(data, false);
|
||||
}
|
||||
|
||||
/* The navigation pointer is set back to zero */
|
||||
@ -1908,6 +1931,7 @@ static void materialui_navigation_clear(void *data, bool pending_push)
|
||||
|
||||
menu_entries_ctl(MENU_ENTRIES_CTL_SET_START, &i);
|
||||
mui->scroll_y = 0;
|
||||
menu_input_set_pointer_y_accel(0.0f);
|
||||
}
|
||||
|
||||
static void materialui_navigation_set_last(void *data)
|
||||
@ -1925,13 +1949,18 @@ static void materialui_populate_entries(
|
||||
void *data, const char *path,
|
||||
const char *label, unsigned i)
|
||||
{
|
||||
materialui_handle_t *mui = (materialui_handle_t*)data;
|
||||
materialui_handle_t *mui = (materialui_handle_t*)data;
|
||||
|
||||
if (!mui)
|
||||
return;
|
||||
|
||||
menu_entries_get_title(mui->menu_title, sizeof(mui->menu_title));
|
||||
mui->need_compute = true;
|
||||
mui->scroll_y = materialui_get_scroll(mui);
|
||||
|
||||
/* Note: mui->scroll_y position needs to be set here,
|
||||
* but we can't do this until materialui_compute_entries_box()
|
||||
* has been called. We therefore delegate it until mui->need_compute
|
||||
* is acted upon */
|
||||
}
|
||||
|
||||
/* Context reset is called on launch or when a core is launched */
|
||||
@ -2902,7 +2931,6 @@ menu_ctx_driver_t menu_ctx_mui = {
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
menu_display_osk_ptr_at_pos,
|
||||
NULL, /* update_savestate_thumbnail_path */
|
||||
NULL, /* update_savestate_thumbnail_image */
|
||||
|
@ -88,7 +88,6 @@ menu_ctx_driver_t menu_ctx_null = {
|
||||
NULL, /* load_image */
|
||||
"null",
|
||||
NULL, /* environ */
|
||||
NULL, /* pointer_tap */
|
||||
NULL, /* update_thumbnail_path */
|
||||
NULL, /* update_thumbnail_image */
|
||||
NULL, /* refresh_thumbnail_image */
|
||||
|
@ -1529,8 +1529,11 @@ static void ozone_frame(void *data, video_frame_info_t *video_info)
|
||||
|
||||
if (ozone->first_frame)
|
||||
{
|
||||
ozone->cursor_x_old = menu_input_mouse_state(MENU_MOUSE_X_AXIS);
|
||||
ozone->cursor_y_old = menu_input_mouse_state(MENU_MOUSE_Y_AXIS);
|
||||
menu_input_pointer_t pointer;
|
||||
menu_input_get_pointer_state(&pointer);
|
||||
|
||||
ozone->cursor_x_old = pointer.x;
|
||||
ozone->cursor_y_old = pointer.y;
|
||||
ozone->first_frame = false;
|
||||
}
|
||||
|
||||
@ -1699,14 +1702,17 @@ static void ozone_frame(void *data, video_frame_info_t *video_info)
|
||||
/* Cursor */
|
||||
if (ozone->show_cursor)
|
||||
{
|
||||
menu_input_pointer_t pointer;
|
||||
menu_input_get_pointer_state(&pointer);
|
||||
|
||||
menu_display_set_alpha(ozone_pure_white, 1.0f);
|
||||
menu_display_draw_cursor(
|
||||
video_info,
|
||||
ozone_pure_white,
|
||||
ozone->dimensions.cursor_size,
|
||||
ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_POINTER],
|
||||
menu_input_mouse_state(MENU_MOUSE_X_AXIS),
|
||||
menu_input_mouse_state(MENU_MOUSE_Y_AXIS),
|
||||
pointer.x,
|
||||
pointer.y,
|
||||
video_info->width,
|
||||
video_info->height
|
||||
);
|
||||
@ -2269,13 +2275,13 @@ static bool ozone_get_load_content_animation_data(void *userdata, menu_texture_i
|
||||
}
|
||||
#endif
|
||||
|
||||
static int ozone_pointer_tap(void *userdata,
|
||||
static int ozone_pointer_up(void *userdata,
|
||||
unsigned x, unsigned y, unsigned ptr,
|
||||
menu_file_list_cbs_t *cbs,
|
||||
menu_entry_t *entry, unsigned action)
|
||||
{
|
||||
size_t selection = menu_navigation_get_selection();
|
||||
if (ptr == selection && cbs && cbs->action_select)
|
||||
if (ptr == selection)
|
||||
return (unsigned)menu_entry_action(entry, (unsigned)selection, MENU_ACTION_SELECT);
|
||||
|
||||
menu_navigation_set_selection(ptr);
|
||||
@ -2435,7 +2441,6 @@ menu_ctx_driver_t menu_ctx_ozone = {
|
||||
ozone_load_image,
|
||||
"ozone",
|
||||
ozone_environ_cb,
|
||||
ozone_pointer_tap,
|
||||
ozone_update_thumbnail_path,
|
||||
ozone_update_thumbnail_image,
|
||||
ozone_refresh_thumbnail_image,
|
||||
@ -2446,7 +2451,7 @@ menu_ctx_driver_t menu_ctx_ozone = {
|
||||
NULL, /* update_savestate_thumbnail_path */
|
||||
NULL, /* update_savestate_thumbnail_image */
|
||||
NULL, /* pointer_down */
|
||||
NULL, /* pointer_up */
|
||||
ozone_pointer_up,
|
||||
#ifdef HAVE_MENU_WIDGETS
|
||||
ozone_get_load_content_animation_data
|
||||
#else
|
||||
|
@ -351,6 +351,7 @@ void ozone_draw_entries(ozone_handle_t *ozone, video_frame_info_t *video_info,
|
||||
size_t i, y, entries_end;
|
||||
float sidebar_offset, bottom_boundary, invert, alpha_anim;
|
||||
unsigned video_info_height, video_info_width, entry_width, button_height;
|
||||
menu_input_pointer_t pointer;
|
||||
settings_t *settings = config_get_ptr();
|
||||
|
||||
bool old_list = selection_buf == ozone->selection_buf_old;
|
||||
@ -359,13 +360,24 @@ void ozone_draw_entries(ozone_handle_t *ozone, video_frame_info_t *video_info,
|
||||
size_t old_selection_y = 0;
|
||||
int entry_padding = ozone_get_entries_padding(ozone, old_list);
|
||||
|
||||
int16_t cursor_x = menu_input_mouse_state(MENU_MOUSE_X_AXIS);
|
||||
int16_t cursor_y = menu_input_mouse_state(MENU_MOUSE_Y_AXIS);
|
||||
int16_t cursor_x = 0;
|
||||
int16_t cursor_y = 0;
|
||||
|
||||
if (settings->bools.menu_mouse_enable && !ozone->cursor_mode && (cursor_x != ozone->cursor_x_old || cursor_y != ozone->cursor_y_old))
|
||||
ozone->cursor_mode = true;
|
||||
else if (!settings->bools.menu_mouse_enable)
|
||||
ozone->cursor_mode = false; /* we need to disable it on the fly */
|
||||
menu_input_get_pointer_state(&pointer);
|
||||
|
||||
if (pointer.type != MENU_POINTER_DISABLED)
|
||||
{
|
||||
cursor_x = pointer.x;
|
||||
cursor_y = pointer.y;
|
||||
|
||||
/* Not sure why it's done like this - best to leave well alone for now... */
|
||||
if (settings->bools.menu_mouse_enable && !ozone->cursor_mode && (cursor_x != ozone->cursor_x_old || cursor_y != ozone->cursor_y_old))
|
||||
ozone->cursor_mode = true;
|
||||
else if (!settings->bools.menu_mouse_enable)
|
||||
ozone->cursor_mode = false; /* we need to disable it on the fly */
|
||||
}
|
||||
else
|
||||
ozone->cursor_mode = false;
|
||||
|
||||
ozone->cursor_x_old = cursor_x;
|
||||
ozone->cursor_y_old = cursor_y;
|
||||
@ -438,15 +450,9 @@ void ozone_draw_entries(ozone_handle_t *ozone, video_frame_info_t *video_info,
|
||||
|
||||
/* Cursor */
|
||||
if (!old_list && ozone->cursor_mode)
|
||||
{
|
||||
if ( cursor_x >= border_start_x && (cursor_x <= border_start_x + (int)entry_width) &&
|
||||
cursor_y >= border_start_y && (cursor_y <= border_start_y + (int)button_height))
|
||||
{
|
||||
selection_y = y;
|
||||
menu_navigation_set_selection(i);
|
||||
menu_input_ctl(MENU_INPUT_CTL_MOUSE_PTR, &i);
|
||||
}
|
||||
}
|
||||
menu_input_set_pointer_selection(i);
|
||||
|
||||
border_iterate:
|
||||
if (node)
|
||||
|
@ -531,7 +531,7 @@ typedef struct
|
||||
bool shadow_enable;
|
||||
unsigned particle_effect;
|
||||
bool extended_ascii_enable;
|
||||
float scroll_y;
|
||||
int16_t scroll_y;
|
||||
char msgbox[1024];
|
||||
unsigned color_theme;
|
||||
rgui_colors_t colors;
|
||||
@ -2824,23 +2824,80 @@ end:
|
||||
string_list_free(list);
|
||||
}
|
||||
|
||||
static void rgui_blit_cursor(void)
|
||||
static void rgui_blit_cursor(rgui_t *rgui)
|
||||
{
|
||||
size_t fb_pitch;
|
||||
unsigned fb_width, fb_height;
|
||||
int16_t x = menu_input_mouse_state(MENU_MOUSE_X_AXIS);
|
||||
int16_t y = menu_input_mouse_state(MENU_MOUSE_Y_AXIS);
|
||||
menu_input_pointer_t pointer;
|
||||
|
||||
menu_display_get_fb_size(&fb_width, &fb_height,
|
||||
&fb_pitch);
|
||||
|
||||
menu_input_get_pointer_state(&pointer);
|
||||
|
||||
if (rgui_frame_buf.data)
|
||||
{
|
||||
rgui_color_rect(rgui_frame_buf.data, fb_width, fb_height, x, y - 5, 1, 11, 0xFFFF);
|
||||
rgui_color_rect(rgui_frame_buf.data, fb_width, fb_height, x - 5, y, 11, 1, 0xFFFF);
|
||||
rgui_color_rect(rgui_frame_buf.data, fb_width, fb_height, pointer.x, pointer.y - 5, 1, 11, rgui->colors.normal_color);
|
||||
rgui_color_rect(rgui_frame_buf.data, fb_width, fb_height, pointer.x - 5, pointer.y, 11, 1, rgui->colors.normal_color);
|
||||
}
|
||||
}
|
||||
|
||||
int rgui_osk_ptr_at_pos(void *data, int x, int y,
|
||||
unsigned width, unsigned height)
|
||||
{
|
||||
/* This is a lazy copy/paste from rgui_render_osk(),
|
||||
* but it will do for now... */
|
||||
size_t fb_pitch;
|
||||
unsigned fb_width, fb_height;
|
||||
size_t key_index;
|
||||
|
||||
unsigned key_width, key_height;
|
||||
unsigned key_text_offset_x, key_text_offset_y;
|
||||
unsigned ptr_width, ptr_height;
|
||||
unsigned ptr_offset_x, ptr_offset_y;
|
||||
|
||||
unsigned keyboard_width, keyboard_height;
|
||||
unsigned keyboard_offset_x, keyboard_offset_y;
|
||||
|
||||
unsigned osk_width, osk_height;
|
||||
unsigned osk_x, osk_y;
|
||||
|
||||
/* Get dimensions/layout */
|
||||
menu_display_get_fb_size(&fb_width, &fb_height, &fb_pitch);
|
||||
|
||||
key_text_offset_x = 8;
|
||||
key_text_offset_y = 6;
|
||||
key_width = FONT_WIDTH + (key_text_offset_x * 2);
|
||||
key_height = FONT_HEIGHT + (key_text_offset_y * 2);
|
||||
ptr_offset_x = 2;
|
||||
ptr_offset_y = 2;
|
||||
ptr_width = key_width - (ptr_offset_x * 2);
|
||||
ptr_height = key_height - (ptr_offset_y * 2);
|
||||
keyboard_width = key_width * OSK_CHARS_PER_LINE;
|
||||
keyboard_height = key_height * 4;
|
||||
keyboard_offset_x = 10;
|
||||
keyboard_offset_y = 10 + 15 + (2 * FONT_HEIGHT_STRIDE);
|
||||
osk_width = keyboard_width + 20;
|
||||
osk_height = keyboard_offset_y + keyboard_height + 10;
|
||||
osk_x = (fb_width - osk_width) / 2;
|
||||
osk_y = (fb_height - osk_height) / 2;
|
||||
|
||||
for (key_index = 0; key_index < 44; key_index++)
|
||||
{
|
||||
unsigned key_row = (unsigned)(key_index / OSK_CHARS_PER_LINE);
|
||||
unsigned key_column = (unsigned)(key_index - (key_row * OSK_CHARS_PER_LINE));
|
||||
|
||||
unsigned osk_ptr_x = osk_x + keyboard_offset_x + ptr_offset_x + (key_column * key_width);
|
||||
unsigned osk_ptr_y = osk_y + keyboard_offset_y + ptr_offset_y + (key_row * key_height);
|
||||
|
||||
if (x > osk_ptr_x && x < osk_ptr_x + ptr_width &&
|
||||
y > osk_ptr_y && y < osk_ptr_y + ptr_height)
|
||||
return (int)key_index;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void rgui_render_osk(
|
||||
rgui_t *rgui,
|
||||
menu_animation_ctx_ticker_t *ticker, menu_animation_ctx_ticker_smooth_t *ticker_smooth,
|
||||
@ -3134,8 +3191,9 @@ static void rgui_render(void *data,
|
||||
size_t i, end, fb_pitch, old_start, new_start;
|
||||
unsigned fb_width, fb_height;
|
||||
int bottom;
|
||||
menu_input_pointer_t pointer;
|
||||
unsigned ticker_x_offset = 0;
|
||||
size_t entries_end = 0;
|
||||
size_t entries_end = menu_entries_get_size();
|
||||
bool msg_force = false;
|
||||
bool fb_size_changed = false;
|
||||
settings_t *settings = config_get_ptr();
|
||||
@ -3144,6 +3202,11 @@ static void rgui_render(void *data,
|
||||
static bool display_kb = false;
|
||||
bool current_display_cb = false;
|
||||
|
||||
bool show_fs_thumbnail =
|
||||
rgui->show_fs_thumbnail &&
|
||||
rgui->entry_has_thumbnail &&
|
||||
(fs_thumbnail.is_valid || (rgui->thumbnail_queue_size > 0));
|
||||
|
||||
/* Sanity check */
|
||||
if (!rgui || !rgui_frame_buf.data || !settings)
|
||||
return;
|
||||
@ -3207,64 +3270,73 @@ static void rgui_render(void *data,
|
||||
|
||||
rgui->force_redraw = false;
|
||||
|
||||
if (settings->bools.menu_pointer_enable)
|
||||
/* Get offset of bottommost entry */
|
||||
bottom = (int)(entries_end - rgui_term_layout.height);
|
||||
menu_entries_ctl(MENU_ENTRIES_CTL_START_GET, &old_start);
|
||||
if (old_start > (unsigned)bottom)
|
||||
{
|
||||
unsigned new_val;
|
||||
/* MENU_ENTRIES_CTL_SET_START requires a pointer of
|
||||
* type size_t, so have to create a copy of 'bottom'
|
||||
* here to avoid memory errors... */
|
||||
size_t bottom_cpy = (size_t)bottom;
|
||||
menu_entries_ctl(MENU_ENTRIES_CTL_SET_START, &bottom_cpy);
|
||||
}
|
||||
|
||||
menu_entries_ctl(MENU_ENTRIES_CTL_START_GET, &old_start);
|
||||
/* Handle pointer input
|
||||
* Note: We'd normally just check pointer.type here but
|
||||
* RGUI focuses on performance - so skip all of this
|
||||
* if both mouse and touchscreen input are disabled by
|
||||
* the user (only saves a dozen or so clock cycles, but
|
||||
* might as well...) */
|
||||
if (settings->bools.menu_mouse_enable || settings->bools.menu_pointer_enable)
|
||||
{
|
||||
menu_input_get_pointer_state(&pointer);
|
||||
|
||||
new_val = (unsigned)(menu_input_pointer_state(MENU_POINTER_Y_AXIS)
|
||||
/ (11 - 2 + old_start));
|
||||
|
||||
menu_input_ctl(MENU_INPUT_CTL_POINTER_PTR, &new_val);
|
||||
|
||||
if (menu_input_ctl(MENU_INPUT_CTL_IS_POINTER_DRAGGED, NULL))
|
||||
/* Ignore input when showing a fullscreen thumbnail */
|
||||
if ((pointer.type != MENU_POINTER_DISABLED) && !show_fs_thumbnail)
|
||||
{
|
||||
size_t start;
|
||||
int16_t delta_y = menu_input_pointer_state(MENU_POINTER_DELTA_Y_AXIS);
|
||||
rgui->scroll_y += delta_y;
|
||||
/* Update currently 'highlighted' item */
|
||||
if (pointer.y > rgui_term_layout.start_y)
|
||||
{
|
||||
unsigned new_ptr;
|
||||
menu_entries_ctl(MENU_ENTRIES_CTL_START_GET, &old_start);
|
||||
|
||||
start = -rgui->scroll_y / 11 + 2;
|
||||
/* Note: It's okay for this to go out of range
|
||||
* (limits are checked in rgui_pointer_up()) */
|
||||
new_ptr = (unsigned)((pointer.y - rgui_term_layout.start_y) / FONT_HEIGHT_STRIDE) + old_start;
|
||||
|
||||
menu_entries_ctl(MENU_ENTRIES_CTL_SET_START, &start);
|
||||
menu_input_set_pointer_selection(new_ptr);
|
||||
}
|
||||
|
||||
if (rgui->scroll_y > 0)
|
||||
rgui->scroll_y = 0;
|
||||
/* Allow drag-scrolling if items are currently off-screen */
|
||||
if (pointer.dragged && (bottom > 0))
|
||||
{
|
||||
size_t start;
|
||||
int16_t scroll_y_max = bottom * FONT_HEIGHT_STRIDE;
|
||||
|
||||
rgui->scroll_y += -1 * pointer.dy;
|
||||
rgui->scroll_y = (rgui->scroll_y < 0) ? 0 : rgui->scroll_y;
|
||||
rgui->scroll_y = (rgui->scroll_y > scroll_y_max) ? scroll_y_max : rgui->scroll_y;
|
||||
|
||||
start = rgui->scroll_y / FONT_HEIGHT_STRIDE;
|
||||
menu_entries_ctl(MENU_ENTRIES_CTL_SET_START, &start);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (settings->bools.menu_mouse_enable)
|
||||
{
|
||||
unsigned new_mouse_ptr;
|
||||
int16_t mouse_y = menu_input_mouse_state(MENU_MOUSE_Y_AXIS);
|
||||
|
||||
menu_entries_ctl(MENU_ENTRIES_CTL_START_GET, &old_start);
|
||||
|
||||
new_mouse_ptr = (unsigned)(mouse_y / 11 - 2 + old_start);
|
||||
|
||||
menu_input_ctl(MENU_INPUT_CTL_MOUSE_PTR, &new_mouse_ptr);
|
||||
}
|
||||
/* Start position may have changed - get current
|
||||
* value and determine index of last displayed entry */
|
||||
menu_entries_ctl(MENU_ENTRIES_CTL_START_GET, &old_start);
|
||||
end = ((old_start + rgui_term_layout.height) <= entries_end) ?
|
||||
old_start + rgui_term_layout.height : entries_end;
|
||||
|
||||
/* Do not scroll if all items are visible. */
|
||||
if (menu_entries_get_size() <= rgui_term_layout.height)
|
||||
if (entries_end <= rgui_term_layout.height)
|
||||
{
|
||||
size_t start = 0;
|
||||
menu_entries_ctl(MENU_ENTRIES_CTL_SET_START, &start);
|
||||
}
|
||||
|
||||
bottom = (int)(menu_entries_get_size() - rgui_term_layout.height);
|
||||
menu_entries_ctl(MENU_ENTRIES_CTL_START_GET, &old_start);
|
||||
|
||||
if (old_start > (unsigned)bottom)
|
||||
menu_entries_ctl(MENU_ENTRIES_CTL_SET_START, &bottom);
|
||||
|
||||
menu_entries_ctl(MENU_ENTRIES_CTL_START_GET, &old_start);
|
||||
|
||||
entries_end = menu_entries_get_size();
|
||||
|
||||
end = ((old_start + rgui_term_layout.height) <= (entries_end)) ?
|
||||
old_start + rgui_term_layout.height : entries_end;
|
||||
|
||||
/* Render background */
|
||||
rgui_render_background();
|
||||
|
||||
@ -3295,7 +3367,7 @@ static void rgui_render(void *data,
|
||||
* normal menu thumbnail/text list display modes */
|
||||
if (current_display_cb)
|
||||
rgui_render_osk(rgui, &ticker, &ticker_smooth, use_smooth_ticker);
|
||||
else if (rgui->show_fs_thumbnail && rgui->entry_has_thumbnail && (fs_thumbnail.is_valid || (rgui->thumbnail_queue_size > 0)))
|
||||
else if (show_fs_thumbnail)
|
||||
{
|
||||
/* If fullscreen thumbnails are enabled and we are viewing a playlist,
|
||||
* switch to fullscreen thumbnail view mode if either current thumbnail
|
||||
@ -3787,7 +3859,7 @@ static void rgui_render(void *data,
|
||||
!video_driver_has_windowed();
|
||||
|
||||
if (settings->bools.menu_mouse_enable && cursor_visible)
|
||||
rgui_blit_cursor();
|
||||
rgui_blit_cursor(rgui);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4226,6 +4298,7 @@ static void *rgui_init(void **userdata, bool video_is_threaded)
|
||||
|
||||
start = 0;
|
||||
menu_entries_ctl(MENU_ENTRIES_CTL_SET_START, &start);
|
||||
rgui->scroll_y = 0;
|
||||
|
||||
rgui_init_font_lut();
|
||||
|
||||
@ -4692,7 +4765,10 @@ static void rgui_navigation_set(void *data, bool scroll)
|
||||
}
|
||||
|
||||
if (do_set_start)
|
||||
{
|
||||
menu_entries_ctl(MENU_ENTRIES_CTL_SET_START, &start);
|
||||
rgui->scroll_y = start * FONT_HEIGHT_STRIDE;
|
||||
}
|
||||
}
|
||||
|
||||
static void rgui_navigation_set_last(void *data)
|
||||
@ -4782,27 +4858,51 @@ static int rgui_environ(enum menu_environ_cb type,
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int rgui_pointer_tap(void *data,
|
||||
static int rgui_pointer_up(void *data,
|
||||
unsigned x, unsigned y,
|
||||
unsigned ptr, menu_file_list_cbs_t *cbs,
|
||||
menu_entry_t *entry, unsigned action)
|
||||
{
|
||||
rgui_t *rgui = (rgui_t*)data;
|
||||
unsigned header_height = menu_display_get_header_height();
|
||||
size_t selection = menu_navigation_get_selection();
|
||||
bool show_fs_thumbnail = false;
|
||||
|
||||
if (y < header_height)
|
||||
{
|
||||
size_t selection = menu_navigation_get_selection();
|
||||
return menu_entry_action(entry, (unsigned)selection, MENU_ACTION_CANCEL);
|
||||
}
|
||||
else if (ptr <= (menu_entries_get_size() - 1))
|
||||
{
|
||||
size_t selection = menu_navigation_get_selection();
|
||||
if (!rgui)
|
||||
return -1;
|
||||
|
||||
if (ptr == selection && cbs && cbs->action_select)
|
||||
show_fs_thumbnail =
|
||||
rgui->show_fs_thumbnail &&
|
||||
rgui->entry_has_thumbnail &&
|
||||
(fs_thumbnail.is_valid || (rgui->thumbnail_queue_size > 0));
|
||||
|
||||
if (show_fs_thumbnail)
|
||||
{
|
||||
/* If we are currently showing a fullscreen thumbnail:
|
||||
* - Must provide a mechanism for toggling it off
|
||||
* - A normal mouse press should just select the current
|
||||
* entry (for which the thumbnail is being shown) */
|
||||
if (y < header_height)
|
||||
rgui_update_thumbnail_image(rgui);
|
||||
else
|
||||
return menu_entry_action(entry, (unsigned)selection, MENU_ACTION_SELECT);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (y < header_height)
|
||||
return menu_entry_action(entry, (unsigned)selection, MENU_ACTION_CANCEL);
|
||||
else if (ptr <= (menu_entries_get_size() - 1))
|
||||
{
|
||||
/* If currently selected item matches 'pointer' value,
|
||||
* perform a MENU_ACTION_SELECT on it */
|
||||
if (ptr == selection)
|
||||
return menu_entry_action(entry, (unsigned)selection, MENU_ACTION_SELECT);
|
||||
|
||||
menu_navigation_set_selection(ptr);
|
||||
menu_driver_navigation_set(false);
|
||||
/* Otherwise, just move the current selection to the
|
||||
* 'pointer' value */
|
||||
menu_navigation_set_selection(ptr);
|
||||
menu_driver_navigation_set(false);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
@ -5065,17 +5165,16 @@ menu_ctx_driver_t menu_ctx_rgui = {
|
||||
rgui_load_image,
|
||||
"rgui",
|
||||
rgui_environ,
|
||||
rgui_pointer_tap,
|
||||
NULL, /* update_thumbnail_path */
|
||||
rgui_update_thumbnail_image,
|
||||
rgui_refresh_thumbnail_image,
|
||||
rgui_set_thumbnail_system,
|
||||
rgui_get_thumbnail_system,
|
||||
NULL, /* set_thumbnail_content */
|
||||
NULL, /* osk_ptr_at_pos */
|
||||
rgui_osk_ptr_at_pos,
|
||||
NULL, /* update_savestate_thumbnail_path */
|
||||
NULL, /* update_savestate_thumbnail_image */
|
||||
NULL, /* pointer_down */
|
||||
NULL, /* pointer_up */
|
||||
rgui_pointer_up, /* pointer_up */
|
||||
NULL, /* get_load_content_animation_data */
|
||||
};
|
||||
|
@ -2655,23 +2655,25 @@ static void stripes_render(void *data,
|
||||
bool is_idle)
|
||||
{
|
||||
size_t i;
|
||||
menu_input_pointer_t pointer;
|
||||
settings_t *settings = config_get_ptr();
|
||||
stripes_handle_t *stripes = (stripes_handle_t*)data;
|
||||
unsigned end = (unsigned)menu_entries_get_size();
|
||||
bool mouse_enable = settings->bools.menu_mouse_enable;
|
||||
bool pointer_enable = settings->bools.menu_pointer_enable;
|
||||
|
||||
if (!stripes)
|
||||
return;
|
||||
|
||||
if (pointer_enable || mouse_enable)
|
||||
menu_input_get_pointer_state(&pointer);
|
||||
|
||||
if (pointer.type != MENU_POINTER_DISABLED)
|
||||
{
|
||||
size_t selection = menu_navigation_get_selection();
|
||||
int16_t pointer_y = menu_input_pointer_state(MENU_POINTER_Y_AXIS);
|
||||
int16_t mouse_y = menu_input_mouse_state(MENU_MOUSE_Y_AXIS)
|
||||
+ (stripes->cursor_size/2);
|
||||
int16_t pointer_y = pointer.y;
|
||||
unsigned first = 0, last = end;
|
||||
|
||||
pointer_y = (pointer.type == MENU_POINTER_MOUSE) ?
|
||||
pointer_y + (stripes->cursor_size/2) : pointer_y;
|
||||
|
||||
if (height)
|
||||
stripes_calculate_visible_range(stripes, height,
|
||||
end, selection, &first, &last);
|
||||
@ -2682,17 +2684,8 @@ static void stripes_render(void *data,
|
||||
+ stripes_item_y(stripes, (int)i, selection);
|
||||
float item_y2 = item_y1 + stripes->icon_size;
|
||||
|
||||
if (pointer_enable)
|
||||
{
|
||||
if (pointer_y > item_y1 && pointer_y < item_y2)
|
||||
menu_input_ctl(MENU_INPUT_CTL_POINTER_PTR, &i);
|
||||
}
|
||||
|
||||
if (mouse_enable)
|
||||
{
|
||||
if (mouse_y > item_y1 && mouse_y < item_y2)
|
||||
menu_input_ctl(MENU_INPUT_CTL_MOUSE_PTR, &i);
|
||||
}
|
||||
if (pointer_y > item_y1 && pointer_y < item_y2)
|
||||
menu_input_set_pointer_selection(i);
|
||||
}
|
||||
}
|
||||
|
||||
@ -3005,14 +2998,17 @@ static void stripes_frame(void *data, video_frame_info_t *video_info)
|
||||
/* Cursor image */
|
||||
if (stripes->mouse_show)
|
||||
{
|
||||
menu_input_pointer_t pointer;
|
||||
menu_input_get_pointer_state(&pointer);
|
||||
|
||||
menu_display_set_alpha(stripes_coord_white, MIN(stripes->alpha, 1.00f));
|
||||
menu_display_draw_cursor(
|
||||
video_info,
|
||||
&stripes_coord_white[0],
|
||||
stripes->cursor_size,
|
||||
stripes->textures.list[STRIPES_TEXTURE_POINTER],
|
||||
menu_input_mouse_state(MENU_MOUSE_X_AXIS),
|
||||
menu_input_mouse_state(MENU_MOUSE_Y_AXIS),
|
||||
pointer.x,
|
||||
pointer.y,
|
||||
width,
|
||||
height);
|
||||
}
|
||||
@ -4390,7 +4386,7 @@ error:
|
||||
return false;
|
||||
}
|
||||
|
||||
static int stripes_pointer_tap(void *userdata,
|
||||
static int stripes_pointer_up(void *userdata,
|
||||
unsigned x, unsigned y, unsigned ptr,
|
||||
menu_file_list_cbs_t *cbs,
|
||||
menu_entry_t *entry, unsigned action)
|
||||
@ -4449,7 +4445,6 @@ menu_ctx_driver_t menu_ctx_stripes = {
|
||||
stripes_load_image,
|
||||
"stripes",
|
||||
stripes_environ,
|
||||
stripes_pointer_tap,
|
||||
stripes_update_thumbnail_path,
|
||||
stripes_update_thumbnail_image,
|
||||
stripes_refresh_thumbnail_image,
|
||||
@ -4460,6 +4455,6 @@ menu_ctx_driver_t menu_ctx_stripes = {
|
||||
stripes_update_savestate_thumbnail_path,
|
||||
stripes_update_savestate_thumbnail_image,
|
||||
NULL, /* pointer_down */
|
||||
NULL, /* pointer_up */
|
||||
stripes_pointer_up, /* pointer_up */
|
||||
NULL /* get_load_content_animation_data */
|
||||
};
|
||||
|
@ -3328,8 +3328,8 @@ static void xmb_render(void *data,
|
||||
unsigned end = (unsigned)menu_entries_get_size();
|
||||
bool mouse_enable = settings->bools.menu_mouse_enable;
|
||||
bool pointer_enable = settings->bools.menu_pointer_enable;
|
||||
|
||||
float scale_factor;
|
||||
menu_input_pointer_t pointer;
|
||||
|
||||
if (!xmb)
|
||||
return;
|
||||
@ -3342,14 +3342,17 @@ static void xmb_render(void *data,
|
||||
|
||||
xmb->previous_scale_factor = scale_factor;
|
||||
|
||||
if (pointer_enable || mouse_enable)
|
||||
menu_input_get_pointer_state(&pointer);
|
||||
|
||||
if (pointer.type != MENU_POINTER_DISABLED)
|
||||
{
|
||||
size_t selection = menu_navigation_get_selection();
|
||||
int16_t pointer_y = menu_input_pointer_state(MENU_POINTER_Y_AXIS);
|
||||
int16_t mouse_y = menu_input_mouse_state(MENU_MOUSE_Y_AXIS)
|
||||
+ (xmb->cursor_size/2);
|
||||
int16_t pointer_y = pointer.y;
|
||||
unsigned first = 0, last = end;
|
||||
|
||||
pointer_y = (pointer.type == MENU_POINTER_MOUSE) ?
|
||||
pointer_y + (xmb->cursor_size/2) : pointer_y;
|
||||
|
||||
if (height)
|
||||
xmb_calculate_visible_range(xmb, height,
|
||||
end, (unsigned)selection, &first, &last);
|
||||
@ -3360,17 +3363,8 @@ static void xmb_render(void *data,
|
||||
+ xmb_item_y(xmb, (int)i, selection);
|
||||
float item_y2 = item_y1 + xmb->icon_size;
|
||||
|
||||
if (pointer_enable)
|
||||
{
|
||||
if (pointer_y > item_y1 && pointer_y < item_y2)
|
||||
menu_input_ctl(MENU_INPUT_CTL_POINTER_PTR, &i);
|
||||
}
|
||||
|
||||
if (mouse_enable)
|
||||
{
|
||||
if (mouse_y > item_y1 && mouse_y < item_y2)
|
||||
menu_input_ctl(MENU_INPUT_CTL_MOUSE_PTR, &i);
|
||||
}
|
||||
if (pointer_y > item_y1 && pointer_y < item_y2)
|
||||
menu_input_set_pointer_selection(i);
|
||||
}
|
||||
}
|
||||
|
||||
@ -4324,14 +4318,17 @@ static void xmb_frame(void *data, video_frame_info_t *video_info)
|
||||
/* Cursor image */
|
||||
if (xmb->mouse_show)
|
||||
{
|
||||
menu_input_pointer_t pointer;
|
||||
menu_input_get_pointer_state(&pointer);
|
||||
|
||||
menu_display_set_alpha(coord_white, MIN(xmb->alpha, 1.00f));
|
||||
menu_display_draw_cursor(
|
||||
video_info,
|
||||
&coord_white[0],
|
||||
xmb->cursor_size,
|
||||
xmb->textures.list[XMB_TEXTURE_POINTER],
|
||||
menu_input_mouse_state(MENU_MOUSE_X_AXIS),
|
||||
menu_input_mouse_state(MENU_MOUSE_Y_AXIS),
|
||||
pointer.x,
|
||||
pointer.y,
|
||||
width,
|
||||
height);
|
||||
}
|
||||
@ -5979,7 +5976,7 @@ error:
|
||||
return false;
|
||||
}
|
||||
|
||||
static int xmb_pointer_tap(void *userdata,
|
||||
static int xmb_pointer_up(void *userdata,
|
||||
unsigned x, unsigned y, unsigned ptr,
|
||||
menu_file_list_cbs_t *cbs,
|
||||
menu_entry_t *entry, unsigned action)
|
||||
@ -5994,7 +5991,7 @@ static int xmb_pointer_tap(void *userdata,
|
||||
else if (ptr <= (menu_entries_get_size() - 1))
|
||||
{
|
||||
size_t selection = menu_navigation_get_selection();
|
||||
if (ptr == selection && cbs && cbs->action_select)
|
||||
if (ptr == selection)
|
||||
return (unsigned)menu_entry_action(entry, (unsigned)selection, MENU_ACTION_SELECT);
|
||||
|
||||
menu_navigation_set_selection(ptr);
|
||||
@ -6060,7 +6057,6 @@ menu_ctx_driver_t menu_ctx_xmb = {
|
||||
xmb_load_image,
|
||||
"xmb",
|
||||
xmb_environ,
|
||||
xmb_pointer_tap,
|
||||
xmb_update_thumbnail_path,
|
||||
xmb_update_thumbnail_image,
|
||||
xmb_refresh_thumbnail_image,
|
||||
@ -6071,7 +6067,7 @@ menu_ctx_driver_t menu_ctx_xmb = {
|
||||
xmb_update_savestate_thumbnail_path,
|
||||
xmb_update_savestate_thumbnail_image,
|
||||
NULL, /* pointer_down */
|
||||
NULL, /* pointer_up */
|
||||
xmb_pointer_up,
|
||||
#ifdef HAVE_MENU_WIDGETS
|
||||
xmb_get_load_content_animation_data
|
||||
#else
|
||||
|
@ -721,7 +721,6 @@ menu_ctx_driver_t menu_ctx_xui = {
|
||||
NULL, /* load_image */
|
||||
"xui",
|
||||
xui_environ,
|
||||
NULL, /* pointer_tap */
|
||||
NULL, /* update_thumbnail_path */
|
||||
NULL, /* update_thumbnail_image */
|
||||
NULL, /* refresh_thumbnail_image */
|
||||
|
@ -66,7 +66,6 @@ enum rarch_menu_ctl_state
|
||||
RARCH_MENU_CTL_FIND_DRIVER,
|
||||
RARCH_MENU_CTL_LIST_FREE,
|
||||
RARCH_MENU_CTL_ENVIRONMENT,
|
||||
RARCH_MENU_CTL_POINTER_TAP,
|
||||
RARCH_MENU_CTL_POINTER_DOWN,
|
||||
RARCH_MENU_CTL_POINTER_UP,
|
||||
RARCH_MENU_CTL_OSK_PTR_AT_POS,
|
||||
@ -305,38 +304,6 @@ enum menu_action
|
||||
MENU_ACTION_POINTER_PRESSED
|
||||
};
|
||||
|
||||
enum menu_input_pointer_state
|
||||
{
|
||||
MENU_POINTER_X_AXIS = 0,
|
||||
MENU_POINTER_Y_AXIS,
|
||||
MENU_POINTER_DELTA_X_AXIS,
|
||||
MENU_POINTER_DELTA_Y_AXIS,
|
||||
MENU_POINTER_PRESSED
|
||||
};
|
||||
|
||||
enum menu_input_mouse_state
|
||||
{
|
||||
MENU_MOUSE_X_AXIS = 0,
|
||||
MENU_MOUSE_Y_AXIS,
|
||||
MENU_MOUSE_LEFT_BUTTON,
|
||||
MENU_MOUSE_RIGHT_BUTTON,
|
||||
MENU_MOUSE_WHEEL_UP,
|
||||
MENU_MOUSE_WHEEL_DOWN,
|
||||
MENU_MOUSE_HORIZ_WHEEL_UP,
|
||||
MENU_MOUSE_HORIZ_WHEEL_DOWN
|
||||
};
|
||||
|
||||
enum menu_input_ctl_state
|
||||
{
|
||||
MENU_INPUT_CTL_NONE = 0,
|
||||
MENU_INPUT_CTL_MOUSE_PTR,
|
||||
MENU_INPUT_CTL_POINTER_PTR,
|
||||
MENU_INPUT_CTL_POINTER_ACCEL_READ,
|
||||
MENU_INPUT_CTL_POINTER_ACCEL_WRITE,
|
||||
MENU_INPUT_CTL_IS_POINTER_DRAGGED,
|
||||
MENU_INPUT_CTL_DEINIT
|
||||
};
|
||||
|
||||
enum playlist_sublabel_runtime
|
||||
{
|
||||
PLAYLIST_RUNTIME_PER_CORE = 0,
|
||||
|
@ -2810,12 +2810,12 @@ void menu_display_snow(int width, int height)
|
||||
|
||||
if (p->alive)
|
||||
{
|
||||
int16_t mouse_x = menu_input_mouse_state(
|
||||
MENU_MOUSE_X_AXIS);
|
||||
menu_input_pointer_t pointer;
|
||||
menu_input_get_pointer_state(&pointer);
|
||||
|
||||
p->y += p->yspeed;
|
||||
p->x += menu_display_scalef(
|
||||
mouse_x, 0, width, -0.3, 0.3);
|
||||
pointer.x, 0, width, -0.3, 0.3);
|
||||
p->x += p->xspeed;
|
||||
|
||||
p->alive = p->y >= 0 && p->y < height
|
||||
@ -3097,6 +3097,10 @@ static bool menu_init(menu_handle_t *menu_data)
|
||||
{
|
||||
settings_t *settings = config_get_ptr();
|
||||
|
||||
/* Ensure that menu pointer input is correctly
|
||||
* initialised */
|
||||
menu_input_reset();
|
||||
|
||||
if (!menu_entries_init())
|
||||
return false;
|
||||
|
||||
@ -3463,7 +3467,7 @@ bool menu_driver_ctl(enum rarch_menu_ctl_state state, void *data)
|
||||
for (i = 0; i < SCROLL_INDEX_SIZE; i++)
|
||||
scroll_index_list[i] = 0;
|
||||
|
||||
menu_input_ctl(MENU_INPUT_CTL_DEINIT, NULL);
|
||||
menu_input_reset();
|
||||
|
||||
if (menu_driver_ctx && menu_driver_ctx->free)
|
||||
menu_driver_ctx->free(menu_userdata);
|
||||
@ -3538,19 +3542,6 @@ bool menu_driver_ctl(enum rarch_menu_ctl_state state, void *data)
|
||||
}
|
||||
}
|
||||
return false;
|
||||
case RARCH_MENU_CTL_POINTER_TAP:
|
||||
{
|
||||
menu_ctx_pointer_t *point = (menu_ctx_pointer_t*)data;
|
||||
if (!menu_driver_ctx || !menu_driver_ctx->pointer_tap)
|
||||
{
|
||||
point->retcode = 0;
|
||||
return false;
|
||||
}
|
||||
point->retcode = menu_driver_ctx->pointer_tap(menu_userdata,
|
||||
point->x, point->y, point->ptr,
|
||||
point->cbs, point->entry, point->action);
|
||||
}
|
||||
break;
|
||||
case RARCH_MENU_CTL_POINTER_DOWN:
|
||||
{
|
||||
menu_ctx_pointer_t *point = (menu_ctx_pointer_t*)data;
|
||||
|
@ -305,9 +305,6 @@ typedef struct menu_ctx_driver
|
||||
bool (*load_image)(void *userdata, void *data, enum menu_image_type type);
|
||||
const char *ident;
|
||||
int (*environ_cb)(enum menu_environ_cb type, void *data, void *userdata);
|
||||
int (*pointer_tap)(void *data, unsigned x, unsigned y, unsigned ptr,
|
||||
menu_file_list_cbs_t *cbs,
|
||||
menu_entry_t *entry, unsigned action);
|
||||
void (*update_thumbnail_path)(void *data, unsigned i, char pos);
|
||||
void (*update_thumbnail_image)(void *data);
|
||||
void (*refresh_thumbnail_image)(void *data);
|
||||
|
@ -29,25 +29,66 @@
|
||||
|
||||
RETRO_BEGIN_DECLS
|
||||
|
||||
#define MENU_INPUT_HIDE_CURSOR_DELAY 4000000 /* 4 seconds */
|
||||
|
||||
#define MENU_INPUT_PRESS_TIME_SHORT 250000 /* 250 ms */
|
||||
#define MENU_INPUT_PRESS_TIME_LONG 1500000 /* 1.5 second */
|
||||
/* (Anthing less than 'short' is considered a tap) */
|
||||
|
||||
#define MENU_INPUT_Y_ACCEL_DECAY_FACTOR 0.96f
|
||||
|
||||
enum menu_pointer_type
|
||||
{
|
||||
MENU_POINTER_DISABLED = 0,
|
||||
MENU_POINTER_MOUSE,
|
||||
MENU_POINTER_TOUCHSCREEN
|
||||
};
|
||||
|
||||
enum menu_input_mouse_hw_id
|
||||
{
|
||||
MENU_MOUSE_X_AXIS = 0,
|
||||
MENU_MOUSE_Y_AXIS,
|
||||
MENU_MOUSE_LEFT_BUTTON,
|
||||
MENU_MOUSE_RIGHT_BUTTON,
|
||||
MENU_MOUSE_WHEEL_UP,
|
||||
MENU_MOUSE_WHEEL_DOWN,
|
||||
MENU_MOUSE_HORIZ_WHEEL_UP,
|
||||
MENU_MOUSE_HORIZ_WHEEL_DOWN
|
||||
};
|
||||
|
||||
/* Defines set of (abstracted) inputs/states
|
||||
* common to mouse + touchscreen hardware */
|
||||
typedef struct menu_input_pointer_hw_state
|
||||
{
|
||||
bool active;
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
bool select_pressed;
|
||||
bool cancel_pressed;
|
||||
bool up_pressed;
|
||||
bool down_pressed;
|
||||
bool left_pressed;
|
||||
bool right_pressed;
|
||||
} menu_input_pointer_hw_state_t;
|
||||
|
||||
typedef struct menu_input_pointer
|
||||
{
|
||||
enum menu_pointer_type type;
|
||||
bool pressed;
|
||||
bool dragged;
|
||||
retro_time_t press_duration;
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
int16_t dx;
|
||||
int16_t dy;
|
||||
float y_accel;
|
||||
} menu_input_pointer_t;
|
||||
|
||||
typedef struct menu_input
|
||||
{
|
||||
struct
|
||||
{
|
||||
unsigned ptr;
|
||||
} mouse;
|
||||
|
||||
struct
|
||||
{
|
||||
bool back;
|
||||
bool pressed[2];
|
||||
int16_t x;
|
||||
int16_t y;
|
||||
int16_t dx;
|
||||
int16_t dy;
|
||||
unsigned ptr;
|
||||
unsigned counter;
|
||||
float accel;
|
||||
} pointer;
|
||||
menu_input_pointer_t pointer;
|
||||
unsigned ptr;
|
||||
bool select_inhibit;
|
||||
} menu_input_t;
|
||||
|
||||
typedef struct menu_input_ctx_hitbox
|
||||
@ -58,16 +99,32 @@ typedef struct menu_input_ctx_hitbox
|
||||
int32_t y2;
|
||||
} menu_input_ctx_hitbox_t;
|
||||
|
||||
/* Must be called inside menu_driver_toggle()
|
||||
* Prevents phantom input when using an overlay to
|
||||
* toggle menu ON if overlays are disabled in-menu */
|
||||
void menu_input_driver_toggle(bool on);
|
||||
|
||||
/* Provides access to all pointer device parameters */
|
||||
void menu_input_get_pointer_state(menu_input_pointer_t *pointer);
|
||||
|
||||
/* Getters/setters for menu item (index) currently
|
||||
* selected/highlighted (hovered over) by the pointer
|
||||
* device
|
||||
* Note: Each menu driver is responsible for setting this */
|
||||
unsigned menu_input_get_pointer_selection(void);
|
||||
void menu_input_set_pointer_selection(unsigned selection);
|
||||
|
||||
/* Allows pointer y acceleration to be overridden
|
||||
* (typically want to set acceleration to zero when
|
||||
* calling populate entries) */
|
||||
void menu_input_set_pointer_y_accel(float y_accel);
|
||||
|
||||
void menu_input_reset(void);
|
||||
|
||||
bool menu_input_pointer_check_vector_inside_hitbox(menu_input_ctx_hitbox_t *hitbox);
|
||||
|
||||
void menu_input_post_iterate(int *ret, unsigned action);
|
||||
|
||||
int16_t menu_input_pointer_state(enum menu_input_pointer_state state);
|
||||
|
||||
int16_t menu_input_mouse_state(enum menu_input_mouse_state state);
|
||||
|
||||
bool menu_input_mouse_check_vector_inside_hitbox(menu_input_ctx_hitbox_t *hitbox);
|
||||
|
||||
bool menu_input_ctl(enum menu_input_ctl_state state, void *data);
|
||||
|
||||
RETRO_END_DECLS
|
||||
|
||||
#endif
|
||||
|
1250
retroarch.c
1250
retroarch.c
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user