Skip to content

Commit

Permalink
Fix scroll wheel mouse position
Browse files Browse the repository at this point in the history
SDL_MouseWheelEvent does not provide the mouse location, so we used
SDL_GetMouseState() to retrieve it.

Unfortunately, SDL_GetMouseState() returns a position expressed in the
window coordinate system while the position filled in SDL events are
expressed in the renderer coordinate system. As a consequence, the
scroll was not applied at the right position on the device.

Therefore, convert the coordinate system.

See <https://stackoverflow.com/questions/49111054/how-to-get-mouse-position-on-mouse-wheel-event>.
  • Loading branch information
rom1v committed Mar 5, 2018
1 parent a82f665 commit 36c68c4
Showing 1 changed file with 16 additions and 2 deletions.
18 changes: 16 additions & 2 deletions app/src/inputmanager.c
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,24 @@
#include "lockutil.h"
#include "log.h"

static struct point get_mouse_point(void) {
// Convert window coordinates (as provided by SDL_GetMouseState() to renderer coordinates (as provided in SDL mouse events)
//
// See my question:
// <https://stackoverflow.com/questions/49111054/how-to-get-mouse-position-on-mouse-wheel-event>
static void convert_to_renderer_coordinates(SDL_Renderer *renderer, int *x, int *y) {
SDL_Rect viewport;
float scale_x, scale_y;
SDL_RenderGetViewport(renderer, &viewport);
SDL_RenderGetScale(renderer, &scale_x, &scale_y);
*x = (int) (*x / scale_x) - viewport.x;
*y = (int) (*y / scale_y) - viewport.y;
}

static struct point get_mouse_point(struct screen *screen) {
int x;
int y;
SDL_GetMouseState(&x, &y);
convert_to_renderer_coordinates(screen->renderer, &x, &y);
SDL_assert_release(x >= 0 && x < 0x10000 && y >= 0 && y < 0x10000);
return (struct point) {
.x = (Uint16) x,
Expand Down Expand Up @@ -204,7 +218,7 @@ void input_manager_process_mouse_wheel(struct input_manager *input_manager,
const SDL_MouseWheelEvent *event) {
struct position position = {
.screen_size = input_manager->screen->frame_size,
.point = get_mouse_point(),
.point = get_mouse_point(input_manager->screen),
};
struct control_event control_event;
if (mouse_wheel_from_sdl_to_android(event, position, &control_event)) {
Expand Down

0 comments on commit 36c68c4

Please sign in to comment.