Overhaul menu mouse/touchscreen input handling

This commit is contained in:
jdgleaver 2019-09-19 16:50:55 +01:00
parent 71cc43651a
commit 8655038601
13 changed files with 1116 additions and 833 deletions

View File

@ -143,6 +143,7 @@ enum
typedef struct materialui_handle typedef struct materialui_handle
{ {
bool need_compute; bool need_compute;
bool need_scroll;
bool mouse_show; bool mouse_show;
int cursor_size; int cursor_size;
@ -645,6 +646,40 @@ static void materialui_compute_entries_box(materialui_handle_t* mui, int width,
mui->content_height = sum; 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 /* Called on each frame. We use this callback to implement the touch scroll
with acceleration */ with acceleration */
static void materialui_render(void *data, static void materialui_render(void *data,
@ -652,6 +687,7 @@ static void materialui_render(void *data,
bool is_idle) bool is_idle)
{ {
unsigned bottom, header_height; unsigned bottom, header_height;
menu_input_pointer_t pointer;
size_t i = 0; size_t i = 0;
materialui_handle_t *mui = (materialui_handle_t*)data; materialui_handle_t *mui = (materialui_handle_t*)data;
settings_t *settings = config_get_ptr(); settings_t *settings = config_get_ptr();
@ -660,61 +696,63 @@ static void materialui_render(void *data,
if (!mui) if (!mui)
return; 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->need_compute)
{ {
if (mui->font) if (mui->font)
materialui_compute_entries_box(mui, width, height); materialui_compute_entries_box(mui, width, height);
mui->need_compute = false; mui->need_compute = false;
mui->need_scroll = true;
} }
menu_display_set_width(width); menu_display_set_width(width);
menu_display_set_height(height); menu_display_set_height(height);
header_height = menu_display_get_header_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; size_t ii;
int16_t pointer_y = menu_input_pointer_state(MENU_POINTER_Y_AXIS); int16_t pointer_y = pointer.y;
float old_accel_val = 0.0f; float old_accel_val = 0.0f;
float new_accel_val = 0.0f; float new_accel_val = 0.0f;
size_t entries_end = menu_entries_get_size(); size_t entries_end = menu_entries_get_size();
for (ii = 0; ii < entries_end; ii++) for (ii = 0; ii < entries_end; ii++)
{ {
materialui_node_t *node = (materialui_node_t*) materialui_node_t *node = (materialui_node_t*)
file_list_get_userdata_at_offset(list, ii); file_list_get_userdata_at_offset(list, ii);
if (pointer_y > (-mui->scroll_y + header_height + node->y) if ((pointer_y > (-mui->scroll_y + header_height + node->y)) &&
&& pointer_y < (-mui->scroll_y + header_height + node->y + node->line_height) (pointer_y < (-mui->scroll_y + header_height + node->y + node->line_height)))
) {
menu_input_ctl(MENU_INPUT_CTL_POINTER_PTR, &ii); menu_input_set_pointer_selection(ii);
break;
}
} }
menu_input_ctl(MENU_INPUT_CTL_POINTER_ACCEL_READ, &old_accel_val); mui->scroll_y -= pointer.y_accel;
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);
}
} }
if (mui->scroll_y < 0) 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) if (mui->mouse_show)
{
menu_input_pointer_t pointer;
menu_input_get_pointer_state(&pointer);
menu_display_draw_cursor( menu_display_draw_cursor(
video_info, video_info,
&white_bg[0], &white_bg[0],
mui->cursor_size, mui->cursor_size,
mui->textures.list[MUI_TEXTURE_POINTER], mui->textures.list[MUI_TEXTURE_POINTER],
menu_input_mouse_state(MENU_MOUSE_X_AXIS), pointer.x,
menu_input_mouse_state(MENU_MOUSE_Y_AXIS), pointer.y,
width, width,
height); height);
}
menu_display_restore_clear_color(); menu_display_restore_clear_color();
menu_display_unset_viewport(video_info->width, video_info->height); 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; *userdata = mui;
mui->cursor_size = scale_factor / 3; mui->cursor_size = scale_factor / 3;
mui->need_compute = false; mui->need_compute = false;
mui->need_scroll = false;
mui->menu_title[0] = '\0'; mui->menu_title[0] = '\0';
@ -1840,36 +1884,6 @@ static bool materialui_load_image(void *userdata, void *data, enum menu_image_ty
return true; 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 /* The navigation pointer has been updated (for example by pressing up or down
on the keyboard). We use this function to animate the scroll. */ on the keyboard). We use this function to animate the scroll. */
static void materialui_navigation_set(void *data, bool 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) if (!mui || !scroll)
return; 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.duration = 166;
entry.target_value = scroll_pos; entry.target_value = scroll_pos;
entry.subject = &mui->scroll_y; 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) 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 */ /* 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); menu_entries_ctl(MENU_ENTRIES_CTL_SET_START, &i);
mui->scroll_y = 0; mui->scroll_y = 0;
menu_input_set_pointer_y_accel(0.0f);
} }
static void materialui_navigation_set_last(void *data) static void materialui_navigation_set_last(void *data)
@ -1925,13 +1949,18 @@ static void materialui_populate_entries(
void *data, const char *path, void *data, const char *path,
const char *label, unsigned i) const char *label, unsigned i)
{ {
materialui_handle_t *mui = (materialui_handle_t*)data; materialui_handle_t *mui = (materialui_handle_t*)data;
if (!mui) if (!mui)
return; return;
menu_entries_get_title(mui->menu_title, sizeof(mui->menu_title)); menu_entries_get_title(mui->menu_title, sizeof(mui->menu_title));
mui->need_compute = true; 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 */ /* 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,
NULL, NULL,
NULL,
menu_display_osk_ptr_at_pos, menu_display_osk_ptr_at_pos,
NULL, /* update_savestate_thumbnail_path */ NULL, /* update_savestate_thumbnail_path */
NULL, /* update_savestate_thumbnail_image */ NULL, /* update_savestate_thumbnail_image */

View File

@ -88,7 +88,6 @@ menu_ctx_driver_t menu_ctx_null = {
NULL, /* load_image */ NULL, /* load_image */
"null", "null",
NULL, /* environ */ NULL, /* environ */
NULL, /* pointer_tap */
NULL, /* update_thumbnail_path */ NULL, /* update_thumbnail_path */
NULL, /* update_thumbnail_image */ NULL, /* update_thumbnail_image */
NULL, /* refresh_thumbnail_image */ NULL, /* refresh_thumbnail_image */

View File

@ -1529,8 +1529,11 @@ static void ozone_frame(void *data, video_frame_info_t *video_info)
if (ozone->first_frame) if (ozone->first_frame)
{ {
ozone->cursor_x_old = menu_input_mouse_state(MENU_MOUSE_X_AXIS); menu_input_pointer_t pointer;
ozone->cursor_y_old = menu_input_mouse_state(MENU_MOUSE_Y_AXIS); menu_input_get_pointer_state(&pointer);
ozone->cursor_x_old = pointer.x;
ozone->cursor_y_old = pointer.y;
ozone->first_frame = false; ozone->first_frame = false;
} }
@ -1699,14 +1702,17 @@ static void ozone_frame(void *data, video_frame_info_t *video_info)
/* Cursor */ /* Cursor */
if (ozone->show_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_set_alpha(ozone_pure_white, 1.0f);
menu_display_draw_cursor( menu_display_draw_cursor(
video_info, video_info,
ozone_pure_white, ozone_pure_white,
ozone->dimensions.cursor_size, ozone->dimensions.cursor_size,
ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_POINTER], ozone->icons_textures[OZONE_ENTRIES_ICONS_TEXTURE_POINTER],
menu_input_mouse_state(MENU_MOUSE_X_AXIS), pointer.x,
menu_input_mouse_state(MENU_MOUSE_Y_AXIS), pointer.y,
video_info->width, video_info->width,
video_info->height video_info->height
); );
@ -2269,13 +2275,13 @@ static bool ozone_get_load_content_animation_data(void *userdata, menu_texture_i
} }
#endif #endif
static int ozone_pointer_tap(void *userdata, static int ozone_pointer_up(void *userdata,
unsigned x, unsigned y, unsigned ptr, unsigned x, unsigned y, unsigned ptr,
menu_file_list_cbs_t *cbs, menu_file_list_cbs_t *cbs,
menu_entry_t *entry, unsigned action) menu_entry_t *entry, unsigned action)
{ {
size_t selection = menu_navigation_get_selection(); 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); return (unsigned)menu_entry_action(entry, (unsigned)selection, MENU_ACTION_SELECT);
menu_navigation_set_selection(ptr); menu_navigation_set_selection(ptr);
@ -2435,7 +2441,6 @@ menu_ctx_driver_t menu_ctx_ozone = {
ozone_load_image, ozone_load_image,
"ozone", "ozone",
ozone_environ_cb, ozone_environ_cb,
ozone_pointer_tap,
ozone_update_thumbnail_path, ozone_update_thumbnail_path,
ozone_update_thumbnail_image, ozone_update_thumbnail_image,
ozone_refresh_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_path */
NULL, /* update_savestate_thumbnail_image */ NULL, /* update_savestate_thumbnail_image */
NULL, /* pointer_down */ NULL, /* pointer_down */
NULL, /* pointer_up */ ozone_pointer_up,
#ifdef HAVE_MENU_WIDGETS #ifdef HAVE_MENU_WIDGETS
ozone_get_load_content_animation_data ozone_get_load_content_animation_data
#else #else

View File

@ -351,6 +351,7 @@ void ozone_draw_entries(ozone_handle_t *ozone, video_frame_info_t *video_info,
size_t i, y, entries_end; size_t i, y, entries_end;
float sidebar_offset, bottom_boundary, invert, alpha_anim; float sidebar_offset, bottom_boundary, invert, alpha_anim;
unsigned video_info_height, video_info_width, entry_width, button_height; unsigned video_info_height, video_info_width, entry_width, button_height;
menu_input_pointer_t pointer;
settings_t *settings = config_get_ptr(); settings_t *settings = config_get_ptr();
bool old_list = selection_buf == ozone->selection_buf_old; 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; size_t old_selection_y = 0;
int entry_padding = ozone_get_entries_padding(ozone, old_list); 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_x = 0;
int16_t cursor_y = menu_input_mouse_state(MENU_MOUSE_Y_AXIS); 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)) menu_input_get_pointer_state(&pointer);
ozone->cursor_mode = true;
else if (!settings->bools.menu_mouse_enable) if (pointer.type != MENU_POINTER_DISABLED)
ozone->cursor_mode = false; /* we need to disable it on the fly */ {
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_x_old = cursor_x;
ozone->cursor_y_old = cursor_y; 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 */ /* Cursor */
if (!old_list && ozone->cursor_mode) if (!old_list && ozone->cursor_mode)
{
if ( cursor_x >= border_start_x && (cursor_x <= border_start_x + (int)entry_width) && 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)) cursor_y >= border_start_y && (cursor_y <= border_start_y + (int)button_height))
{ menu_input_set_pointer_selection(i);
selection_y = y;
menu_navigation_set_selection(i);
menu_input_ctl(MENU_INPUT_CTL_MOUSE_PTR, &i);
}
}
border_iterate: border_iterate:
if (node) if (node)

View File

@ -531,7 +531,7 @@ typedef struct
bool shadow_enable; bool shadow_enable;
unsigned particle_effect; unsigned particle_effect;
bool extended_ascii_enable; bool extended_ascii_enable;
float scroll_y; int16_t scroll_y;
char msgbox[1024]; char msgbox[1024];
unsigned color_theme; unsigned color_theme;
rgui_colors_t colors; rgui_colors_t colors;
@ -2824,23 +2824,80 @@ end:
string_list_free(list); string_list_free(list);
} }
static void rgui_blit_cursor(void) static void rgui_blit_cursor(rgui_t *rgui)
{ {
size_t fb_pitch; size_t fb_pitch;
unsigned fb_width, fb_height; unsigned fb_width, fb_height;
int16_t x = menu_input_mouse_state(MENU_MOUSE_X_AXIS); menu_input_pointer_t pointer;
int16_t y = menu_input_mouse_state(MENU_MOUSE_Y_AXIS);
menu_display_get_fb_size(&fb_width, &fb_height, menu_display_get_fb_size(&fb_width, &fb_height,
&fb_pitch); &fb_pitch);
menu_input_get_pointer_state(&pointer);
if (rgui_frame_buf.data) 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, pointer.x, pointer.y - 5, 1, 11, rgui->colors.normal_color);
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 - 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( static void rgui_render_osk(
rgui_t *rgui, rgui_t *rgui,
menu_animation_ctx_ticker_t *ticker, menu_animation_ctx_ticker_smooth_t *ticker_smooth, 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; size_t i, end, fb_pitch, old_start, new_start;
unsigned fb_width, fb_height; unsigned fb_width, fb_height;
int bottom; int bottom;
menu_input_pointer_t pointer;
unsigned ticker_x_offset = 0; unsigned ticker_x_offset = 0;
size_t entries_end = 0; size_t entries_end = menu_entries_get_size();
bool msg_force = false; bool msg_force = false;
bool fb_size_changed = false; bool fb_size_changed = false;
settings_t *settings = config_get_ptr(); settings_t *settings = config_get_ptr();
@ -3144,6 +3202,11 @@ static void rgui_render(void *data,
static bool display_kb = false; static bool display_kb = false;
bool current_display_cb = 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 */ /* Sanity check */
if (!rgui || !rgui_frame_buf.data || !settings) if (!rgui || !rgui_frame_buf.data || !settings)
return; return;
@ -3207,64 +3270,73 @@ static void rgui_render(void *data,
rgui->force_redraw = false; 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) /* Ignore input when showing a fullscreen thumbnail */
/ (11 - 2 + old_start)); if ((pointer.type != MENU_POINTER_DISABLED) && !show_fs_thumbnail)
menu_input_ctl(MENU_INPUT_CTL_POINTER_PTR, &new_val);
if (menu_input_ctl(MENU_INPUT_CTL_IS_POINTER_DRAGGED, NULL))
{ {
size_t start; /* Update currently 'highlighted' item */
int16_t delta_y = menu_input_pointer_state(MENU_POINTER_DELTA_Y_AXIS); if (pointer.y > rgui_term_layout.start_y)
rgui->scroll_y += delta_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) /* Allow drag-scrolling if items are currently off-screen */
rgui->scroll_y = 0; 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) /* Start position may have changed - get current
{ * value and determine index of last displayed entry */
unsigned new_mouse_ptr; menu_entries_ctl(MENU_ENTRIES_CTL_START_GET, &old_start);
int16_t mouse_y = menu_input_mouse_state(MENU_MOUSE_Y_AXIS); end = ((old_start + rgui_term_layout.height) <= entries_end) ?
old_start + rgui_term_layout.height : entries_end;
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);
}
/* Do not scroll if all items are visible. */ /* 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; size_t start = 0;
menu_entries_ctl(MENU_ENTRIES_CTL_SET_START, &start); 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 */ /* Render background */
rgui_render_background(); rgui_render_background();
@ -3295,7 +3367,7 @@ static void rgui_render(void *data,
* normal menu thumbnail/text list display modes */ * normal menu thumbnail/text list display modes */
if (current_display_cb) if (current_display_cb)
rgui_render_osk(rgui, &ticker, &ticker_smooth, use_smooth_ticker); 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, /* If fullscreen thumbnails are enabled and we are viewing a playlist,
* switch to fullscreen thumbnail view mode if either current thumbnail * switch to fullscreen thumbnail view mode if either current thumbnail
@ -3787,7 +3859,7 @@ static void rgui_render(void *data,
!video_driver_has_windowed(); !video_driver_has_windowed();
if (settings->bools.menu_mouse_enable && cursor_visible) 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; start = 0;
menu_entries_ctl(MENU_ENTRIES_CTL_SET_START, &start); menu_entries_ctl(MENU_ENTRIES_CTL_SET_START, &start);
rgui->scroll_y = 0;
rgui_init_font_lut(); rgui_init_font_lut();
@ -4692,7 +4765,10 @@ static void rgui_navigation_set(void *data, bool scroll)
} }
if (do_set_start) if (do_set_start)
{
menu_entries_ctl(MENU_ENTRIES_CTL_SET_START, &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) static void rgui_navigation_set_last(void *data)
@ -4782,27 +4858,51 @@ static int rgui_environ(enum menu_environ_cb type,
return -1; return -1;
} }
static int rgui_pointer_tap(void *data, static int rgui_pointer_up(void *data,
unsigned x, unsigned y, unsigned x, unsigned y,
unsigned ptr, menu_file_list_cbs_t *cbs, unsigned ptr, menu_file_list_cbs_t *cbs,
menu_entry_t *entry, unsigned action) menu_entry_t *entry, unsigned action)
{ {
rgui_t *rgui = (rgui_t*)data;
unsigned header_height = menu_display_get_header_height(); unsigned header_height = menu_display_get_header_height();
size_t selection = menu_navigation_get_selection();
bool show_fs_thumbnail = false;
if (y < header_height) if (!rgui)
{ return -1;
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 (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); 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); /* Otherwise, just move the current selection to the
menu_driver_navigation_set(false); * 'pointer' value */
menu_navigation_set_selection(ptr);
menu_driver_navigation_set(false);
}
} }
return 0; return 0;
@ -5065,17 +5165,16 @@ menu_ctx_driver_t menu_ctx_rgui = {
rgui_load_image, rgui_load_image,
"rgui", "rgui",
rgui_environ, rgui_environ,
rgui_pointer_tap,
NULL, /* update_thumbnail_path */ NULL, /* update_thumbnail_path */
rgui_update_thumbnail_image, rgui_update_thumbnail_image,
rgui_refresh_thumbnail_image, rgui_refresh_thumbnail_image,
rgui_set_thumbnail_system, rgui_set_thumbnail_system,
rgui_get_thumbnail_system, rgui_get_thumbnail_system,
NULL, /* set_thumbnail_content */ NULL, /* set_thumbnail_content */
NULL, /* osk_ptr_at_pos */ rgui_osk_ptr_at_pos,
NULL, /* update_savestate_thumbnail_path */ NULL, /* update_savestate_thumbnail_path */
NULL, /* update_savestate_thumbnail_image */ NULL, /* update_savestate_thumbnail_image */
NULL, /* pointer_down */ NULL, /* pointer_down */
NULL, /* pointer_up */ rgui_pointer_up, /* pointer_up */
NULL, /* get_load_content_animation_data */ NULL, /* get_load_content_animation_data */
}; };

View File

@ -2655,23 +2655,25 @@ static void stripes_render(void *data,
bool is_idle) bool is_idle)
{ {
size_t i; size_t i;
menu_input_pointer_t pointer;
settings_t *settings = config_get_ptr(); settings_t *settings = config_get_ptr();
stripes_handle_t *stripes = (stripes_handle_t*)data; stripes_handle_t *stripes = (stripes_handle_t*)data;
unsigned end = (unsigned)menu_entries_get_size(); 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) if (!stripes)
return; 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(); size_t selection = menu_navigation_get_selection();
int16_t pointer_y = menu_input_pointer_state(MENU_POINTER_Y_AXIS); int16_t pointer_y = pointer.y;
int16_t mouse_y = menu_input_mouse_state(MENU_MOUSE_Y_AXIS)
+ (stripes->cursor_size/2);
unsigned first = 0, last = end; unsigned first = 0, last = end;
pointer_y = (pointer.type == MENU_POINTER_MOUSE) ?
pointer_y + (stripes->cursor_size/2) : pointer_y;
if (height) if (height)
stripes_calculate_visible_range(stripes, height, stripes_calculate_visible_range(stripes, height,
end, selection, &first, &last); end, selection, &first, &last);
@ -2682,17 +2684,8 @@ static void stripes_render(void *data,
+ stripes_item_y(stripes, (int)i, selection); + stripes_item_y(stripes, (int)i, selection);
float item_y2 = item_y1 + stripes->icon_size; float item_y2 = item_y1 + stripes->icon_size;
if (pointer_enable) if (pointer_y > item_y1 && pointer_y < item_y2)
{ menu_input_set_pointer_selection(i);
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);
}
} }
} }
@ -3005,14 +2998,17 @@ static void stripes_frame(void *data, video_frame_info_t *video_info)
/* Cursor image */ /* Cursor image */
if (stripes->mouse_show) 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_set_alpha(stripes_coord_white, MIN(stripes->alpha, 1.00f));
menu_display_draw_cursor( menu_display_draw_cursor(
video_info, video_info,
&stripes_coord_white[0], &stripes_coord_white[0],
stripes->cursor_size, stripes->cursor_size,
stripes->textures.list[STRIPES_TEXTURE_POINTER], stripes->textures.list[STRIPES_TEXTURE_POINTER],
menu_input_mouse_state(MENU_MOUSE_X_AXIS), pointer.x,
menu_input_mouse_state(MENU_MOUSE_Y_AXIS), pointer.y,
width, width,
height); height);
} }
@ -4390,7 +4386,7 @@ error:
return false; return false;
} }
static int stripes_pointer_tap(void *userdata, static int stripes_pointer_up(void *userdata,
unsigned x, unsigned y, unsigned ptr, unsigned x, unsigned y, unsigned ptr,
menu_file_list_cbs_t *cbs, menu_file_list_cbs_t *cbs,
menu_entry_t *entry, unsigned action) menu_entry_t *entry, unsigned action)
@ -4449,7 +4445,6 @@ menu_ctx_driver_t menu_ctx_stripes = {
stripes_load_image, stripes_load_image,
"stripes", "stripes",
stripes_environ, stripes_environ,
stripes_pointer_tap,
stripes_update_thumbnail_path, stripes_update_thumbnail_path,
stripes_update_thumbnail_image, stripes_update_thumbnail_image,
stripes_refresh_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_path,
stripes_update_savestate_thumbnail_image, stripes_update_savestate_thumbnail_image,
NULL, /* pointer_down */ NULL, /* pointer_down */
NULL, /* pointer_up */ stripes_pointer_up, /* pointer_up */
NULL /* get_load_content_animation_data */ NULL /* get_load_content_animation_data */
}; };

View File

@ -3328,8 +3328,8 @@ static void xmb_render(void *data,
unsigned end = (unsigned)menu_entries_get_size(); unsigned end = (unsigned)menu_entries_get_size();
bool mouse_enable = settings->bools.menu_mouse_enable; bool mouse_enable = settings->bools.menu_mouse_enable;
bool pointer_enable = settings->bools.menu_pointer_enable; bool pointer_enable = settings->bools.menu_pointer_enable;
float scale_factor; float scale_factor;
menu_input_pointer_t pointer;
if (!xmb) if (!xmb)
return; return;
@ -3342,14 +3342,17 @@ static void xmb_render(void *data,
xmb->previous_scale_factor = scale_factor; 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(); size_t selection = menu_navigation_get_selection();
int16_t pointer_y = menu_input_pointer_state(MENU_POINTER_Y_AXIS); int16_t pointer_y = pointer.y;
int16_t mouse_y = menu_input_mouse_state(MENU_MOUSE_Y_AXIS)
+ (xmb->cursor_size/2);
unsigned first = 0, last = end; unsigned first = 0, last = end;
pointer_y = (pointer.type == MENU_POINTER_MOUSE) ?
pointer_y + (xmb->cursor_size/2) : pointer_y;
if (height) if (height)
xmb_calculate_visible_range(xmb, height, xmb_calculate_visible_range(xmb, height,
end, (unsigned)selection, &first, &last); end, (unsigned)selection, &first, &last);
@ -3360,17 +3363,8 @@ static void xmb_render(void *data,
+ xmb_item_y(xmb, (int)i, selection); + xmb_item_y(xmb, (int)i, selection);
float item_y2 = item_y1 + xmb->icon_size; float item_y2 = item_y1 + xmb->icon_size;
if (pointer_enable) if (pointer_y > item_y1 && pointer_y < item_y2)
{ menu_input_set_pointer_selection(i);
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);
}
} }
} }
@ -4324,14 +4318,17 @@ static void xmb_frame(void *data, video_frame_info_t *video_info)
/* Cursor image */ /* Cursor image */
if (xmb->mouse_show) 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_set_alpha(coord_white, MIN(xmb->alpha, 1.00f));
menu_display_draw_cursor( menu_display_draw_cursor(
video_info, video_info,
&coord_white[0], &coord_white[0],
xmb->cursor_size, xmb->cursor_size,
xmb->textures.list[XMB_TEXTURE_POINTER], xmb->textures.list[XMB_TEXTURE_POINTER],
menu_input_mouse_state(MENU_MOUSE_X_AXIS), pointer.x,
menu_input_mouse_state(MENU_MOUSE_Y_AXIS), pointer.y,
width, width,
height); height);
} }
@ -5979,7 +5976,7 @@ error:
return false; return false;
} }
static int xmb_pointer_tap(void *userdata, static int xmb_pointer_up(void *userdata,
unsigned x, unsigned y, unsigned ptr, unsigned x, unsigned y, unsigned ptr,
menu_file_list_cbs_t *cbs, menu_file_list_cbs_t *cbs,
menu_entry_t *entry, unsigned action) 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)) else if (ptr <= (menu_entries_get_size() - 1))
{ {
size_t selection = menu_navigation_get_selection(); 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); return (unsigned)menu_entry_action(entry, (unsigned)selection, MENU_ACTION_SELECT);
menu_navigation_set_selection(ptr); menu_navigation_set_selection(ptr);
@ -6060,7 +6057,6 @@ menu_ctx_driver_t menu_ctx_xmb = {
xmb_load_image, xmb_load_image,
"xmb", "xmb",
xmb_environ, xmb_environ,
xmb_pointer_tap,
xmb_update_thumbnail_path, xmb_update_thumbnail_path,
xmb_update_thumbnail_image, xmb_update_thumbnail_image,
xmb_refresh_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_path,
xmb_update_savestate_thumbnail_image, xmb_update_savestate_thumbnail_image,
NULL, /* pointer_down */ NULL, /* pointer_down */
NULL, /* pointer_up */ xmb_pointer_up,
#ifdef HAVE_MENU_WIDGETS #ifdef HAVE_MENU_WIDGETS
xmb_get_load_content_animation_data xmb_get_load_content_animation_data
#else #else

View File

@ -721,7 +721,6 @@ menu_ctx_driver_t menu_ctx_xui = {
NULL, /* load_image */ NULL, /* load_image */
"xui", "xui",
xui_environ, xui_environ,
NULL, /* pointer_tap */
NULL, /* update_thumbnail_path */ NULL, /* update_thumbnail_path */
NULL, /* update_thumbnail_image */ NULL, /* update_thumbnail_image */
NULL, /* refresh_thumbnail_image */ NULL, /* refresh_thumbnail_image */

View File

@ -66,7 +66,6 @@ enum rarch_menu_ctl_state
RARCH_MENU_CTL_FIND_DRIVER, RARCH_MENU_CTL_FIND_DRIVER,
RARCH_MENU_CTL_LIST_FREE, RARCH_MENU_CTL_LIST_FREE,
RARCH_MENU_CTL_ENVIRONMENT, RARCH_MENU_CTL_ENVIRONMENT,
RARCH_MENU_CTL_POINTER_TAP,
RARCH_MENU_CTL_POINTER_DOWN, RARCH_MENU_CTL_POINTER_DOWN,
RARCH_MENU_CTL_POINTER_UP, RARCH_MENU_CTL_POINTER_UP,
RARCH_MENU_CTL_OSK_PTR_AT_POS, RARCH_MENU_CTL_OSK_PTR_AT_POS,
@ -305,38 +304,6 @@ enum menu_action
MENU_ACTION_POINTER_PRESSED 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 enum playlist_sublabel_runtime
{ {
PLAYLIST_RUNTIME_PER_CORE = 0, PLAYLIST_RUNTIME_PER_CORE = 0,

View File

@ -2810,12 +2810,12 @@ void menu_display_snow(int width, int height)
if (p->alive) if (p->alive)
{ {
int16_t mouse_x = menu_input_mouse_state( menu_input_pointer_t pointer;
MENU_MOUSE_X_AXIS); menu_input_get_pointer_state(&pointer);
p->y += p->yspeed; p->y += p->yspeed;
p->x += menu_display_scalef( 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->x += p->xspeed;
p->alive = p->y >= 0 && p->y < height 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(); settings_t *settings = config_get_ptr();
/* Ensure that menu pointer input is correctly
* initialised */
menu_input_reset();
if (!menu_entries_init()) if (!menu_entries_init())
return false; 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++) for (i = 0; i < SCROLL_INDEX_SIZE; i++)
scroll_index_list[i] = 0; scroll_index_list[i] = 0;
menu_input_ctl(MENU_INPUT_CTL_DEINIT, NULL); menu_input_reset();
if (menu_driver_ctx && menu_driver_ctx->free) if (menu_driver_ctx && menu_driver_ctx->free)
menu_driver_ctx->free(menu_userdata); menu_driver_ctx->free(menu_userdata);
@ -3538,19 +3542,6 @@ bool menu_driver_ctl(enum rarch_menu_ctl_state state, void *data)
} }
} }
return false; 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: case RARCH_MENU_CTL_POINTER_DOWN:
{ {
menu_ctx_pointer_t *point = (menu_ctx_pointer_t*)data; menu_ctx_pointer_t *point = (menu_ctx_pointer_t*)data;

View File

@ -305,9 +305,6 @@ typedef struct menu_ctx_driver
bool (*load_image)(void *userdata, void *data, enum menu_image_type type); bool (*load_image)(void *userdata, void *data, enum menu_image_type type);
const char *ident; const char *ident;
int (*environ_cb)(enum menu_environ_cb type, void *data, void *userdata); 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_path)(void *data, unsigned i, char pos);
void (*update_thumbnail_image)(void *data); void (*update_thumbnail_image)(void *data);
void (*refresh_thumbnail_image)(void *data); void (*refresh_thumbnail_image)(void *data);

View File

@ -29,25 +29,66 @@
RETRO_BEGIN_DECLS 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 typedef struct menu_input
{ {
struct menu_input_pointer_t pointer;
{ unsigned ptr;
unsigned ptr; bool select_inhibit;
} 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_t; } menu_input_t;
typedef struct menu_input_ctx_hitbox typedef struct menu_input_ctx_hitbox
@ -58,16 +99,32 @@ typedef struct menu_input_ctx_hitbox
int32_t y2; int32_t y2;
} menu_input_ctx_hitbox_t; } 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); 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 RETRO_END_DECLS
#endif #endif

File diff suppressed because it is too large Load Diff