From 91c1517c44409fcf8bf6ba8081e74de04fa6de1c Mon Sep 17 00:00:00 2001 From: Ingo Ruhnke Date: Fri, 1 Aug 2014 03:43:48 +0200 Subject: [PATCH] Pass mouse coordinates to mouse pointer manually instead of SDL_GetMouseState(), see bug #2442 in SDL2 --- src/gui/menu.cpp | 99 ++++++++++++++++++++++++++--------------- src/gui/mousecursor.cpp | 25 +++++++---- src/gui/mousecursor.hpp | 6 +++ 3 files changed, 84 insertions(+), 46 deletions(-) diff --git a/src/gui/menu.cpp b/src/gui/menu.cpp index e3fce4b5d51..583cbb0437c 100644 --- a/src/gui/menu.cpp +++ b/src/gui/menu.cpp @@ -768,53 +768,78 @@ Menu::event(const SDL_Event& event) return; switch(event.type) { - case SDL_MOUSEBUTTONDOWN: - if(event.button.button == SDL_BUTTON_LEFT) - { - Vector mouse_pos = Renderer::instance()->to_logical(event.motion.x, event.motion.y); - int x = int(mouse_pos.x); - int y = int(mouse_pos.y); - - if(x > pos.x - get_width()/2 && - x < pos.x + get_width()/2 && - y > pos.y - get_height()/2 && - y < pos.y + get_height()/2) + case SDL_MOUSEBUTTONUP: { - menuaction = MENU_ACTION_HIT; + Vector mouse_pos = Renderer::instance()->to_logical(event.button.x, event.button.y); + + if(MouseCursor::current()) + { + MouseCursor::current()->set_pos(mouse_pos); + } } - } - break; + break; - case SDL_MOUSEMOTION: - { - Vector mouse_pos = Renderer::instance()->to_logical(event.motion.x, event.motion.y); - float x = mouse_pos.x; - float y = mouse_pos.y; - - if(x > pos.x - get_width()/2 && - x < pos.x + get_width()/2 && - y > pos.y - get_height()/2 && - y < pos.y + get_height()/2) + case SDL_MOUSEBUTTONDOWN: { - int new_active_item - = static_cast ((y - (pos.y - get_height()/2)) / 24); - - /* only change the mouse focus to a selectable item */ - if ((items[new_active_item]->kind != MN_HL) - && (items[new_active_item]->kind != MN_LABEL) - && (items[new_active_item]->kind != MN_INACTIVE)) - active_item = new_active_item; + Vector mouse_pos = Renderer::instance()->to_logical(event.button.x, event.button.y); if(MouseCursor::current()) - MouseCursor::current()->set_state(MC_LINK); + { + MouseCursor::current()->set_pos(mouse_pos); + } + + if(event.button.button == SDL_BUTTON_LEFT) + { + int x = int(mouse_pos.x); + int y = int(mouse_pos.y); + + if(x > pos.x - get_width()/2 && + x < pos.x + get_width()/2 && + y > pos.y - get_height()/2 && + y < pos.y + get_height()/2) + { + menuaction = MENU_ACTION_HIT; + } + } } - else + break; + + case SDL_MOUSEMOTION: { + Vector mouse_pos = Renderer::instance()->to_logical(event.motion.x, event.motion.y); + if(MouseCursor::current()) - MouseCursor::current()->set_state(MC_NORMAL); + { + MouseCursor::current()->set_pos(mouse_pos); + } + + float x = mouse_pos.x; + float y = mouse_pos.y; + + if(x > pos.x - get_width()/2 && + x < pos.x + get_width()/2 && + y > pos.y - get_height()/2 && + y < pos.y + get_height()/2) + { + int new_active_item + = static_cast ((y - (pos.y - get_height()/2)) / 24); + + /* only change the mouse focus to a selectable item */ + if ((items[new_active_item]->kind != MN_HL) + && (items[new_active_item]->kind != MN_LABEL) + && (items[new_active_item]->kind != MN_INACTIVE)) + active_item = new_active_item; + + if(MouseCursor::current()) + MouseCursor::current()->set_state(MC_LINK); + } + else + { + if(MouseCursor::current()) + MouseCursor::current()->set_state(MC_NORMAL); + } } - } - break; + break; default: break; diff --git a/src/gui/mousecursor.cpp b/src/gui/mousecursor.cpp index 3248b2b7177..3e86bfc8bea 100644 --- a/src/gui/mousecursor.cpp +++ b/src/gui/mousecursor.cpp @@ -26,6 +26,7 @@ MouseCursor* MouseCursor::current_ = 0; MouseCursor::MouseCursor(std::string cursor_file) : + mouse_pos(), mid_x(0), mid_y(0), state_before_click(), @@ -51,6 +52,12 @@ void MouseCursor::set_state(int nstate) cur_state = nstate; } +void +MouseCursor::set_pos(const Vector& pos) +{ + mouse_pos = pos; +} + void MouseCursor::set_mid(int x, int y) { mid_x = x; @@ -62,17 +69,17 @@ void MouseCursor::draw(DrawingContext& context) if(cur_state == MC_HIDE) return; - int x,y,w,h; - Uint8 ispressed = SDL_GetMouseState(&x,&y); - - Vector mouse_pos = Renderer::instance()->to_logical(x, y, true); + // Not using coordinates from mouse, as they are in the wrong + // coordinate system, see: + // https://bugzilla.libsdl.org/show_bug.cgi?id=2442 + Uint8 ispressed = SDL_GetMouseState(NULL, NULL); - x = int(mouse_pos.x); - y = int(mouse_pos.y); + int x = int(mouse_pos.x); + int y = int(mouse_pos.y); - w = (int) cursor->get_width(); - h = (int) (cursor->get_height() / MC_STATES_NB); - if(ispressed &SDL_BUTTON(1) || ispressed &SDL_BUTTON(2)) { + int w = (int) cursor->get_width(); + int h = (int) (cursor->get_height() / MC_STATES_NB); + if(ispressed & SDL_BUTTON(1) || ispressed & SDL_BUTTON(2)) { if(cur_state != MC_CLICK) { state_before_click = cur_state; cur_state = MC_CLICK; diff --git a/src/gui/mousecursor.hpp b/src/gui/mousecursor.hpp index 30afd565537..329f225f26f 100644 --- a/src/gui/mousecursor.hpp +++ b/src/gui/mousecursor.hpp @@ -19,6 +19,7 @@ #include +#include "math/vector.hpp" #include "video/surface_ptr.hpp" #define MC_STATES_NB 3 @@ -31,6 +32,7 @@ enum { }; class DrawingContext; +class Vector; /// Mouse cursor. /** Used to create mouse cursors. @@ -54,6 +56,9 @@ class MouseCursor /** Useful for cross mouse cursor images in example. */ void set_mid(int x, int y); + /** Set the position where the cursor should appear */ + void set_pos(const Vector& pos); + /// Draw MouseCursor on screen. void draw(DrawingContext& context); @@ -67,6 +72,7 @@ class MouseCursor friend class Resources; private: + Vector mouse_pos; int mid_x; int mid_y; int state_before_click;