Author: mordante
Date: Sun Apr 27 10:08:36 2008
New Revision: 26162

URL: http://svn.gna.org/viewcvs/wesnoth?rev=26162&view=rev
Log:
Made the mouse button handeling generic and implement the middle and right 
button.
Also fixes a minor bug in the the text_box where a mouse out of the widget when
not captured never recieved the mouse up.

Modified:
    trunk/src/gui/widgets/event_handler.cpp
    trunk/src/gui/widgets/event_handler.hpp
    trunk/src/gui/widgets/text.cpp
    trunk/src/gui/widgets/text_box.cpp
    trunk/src/gui/widgets/widget.hpp

Modified: trunk/src/gui/widgets/event_handler.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/gui/widgets/event_handler.cpp?rev=26162&r1=26161&r2=26162&view=diff
==============================================================================
--- trunk/src/gui/widgets/event_handler.cpp (original)
+++ trunk/src/gui/widgets/event_handler.cpp Sun Apr 27 10:08:36 2008
@@ -81,12 +81,24 @@
        event_context_(),
        mouse_x_(-1),
        mouse_y_(-1),
-       mouse_left_button_down_(false),
-       mouse_middle_button_down_(false),
-       mouse_right_button_down_(false),
-       last_left_click_(0),
-       last_middle_click_(0),
-       last_right_click_(0),
+       left_("left",
+               &tevent_executor::mouse_left_button_down,
+               &tevent_executor::mouse_left_button_up,
+               &tevent_executor::mouse_left_button_click,
+               &tevent_executor::mouse_left_button_double_click,
+               &tevent_executor::wants_mouse_left_double_click),
+       middle_("middle",
+               &tevent_executor::mouse_middle_button_down,
+               &tevent_executor::mouse_middle_button_up,
+               &tevent_executor::mouse_middle_button_click,
+               &tevent_executor::mouse_middle_button_double_click,
+               &tevent_executor::wants_mouse_middle_double_click),
+       right_("right",
+               &tevent_executor::mouse_right_button_down,
+               &tevent_executor::mouse_right_button_up,
+               &tevent_executor::mouse_right_button_click,
+               &tevent_executor::mouse_right_button_double_click,
+               &tevent_executor::wants_mouse_right_double_click),
        hover_pending_(false),
        hover_id_(0),
        hover_box_(),
@@ -132,12 +144,19 @@
 
                        switch(event.button.button) {
                                case SDL_BUTTON_LEFT : 
-                                       mouse_left_button_down(event, 
mouse_over);
+                                       mouse_button_down(event, mouse_over, 
left_);
+                                       break;
+                               case SDL_BUTTON_MIDDLE :
+                                       mouse_button_down(event, mouse_over, 
middle_);
+                                       break;
+                               case SDL_BUTTON_RIGHT :
+                                       mouse_button_down(event, mouse_over, 
right_);
                                        break;
                                default:
                                        // cast to avoid being printed as char.
                                        WRN_G_E << "Unhandled 'mouse button 
down' event for button " 
                                                << 
static_cast<Uint32>(event.button.button) << ".\n";
+                                       assert(false);
                                        break;
                        }
                        break;
@@ -152,12 +171,19 @@
                        switch(event.button.button) {
 
                                case SDL_BUTTON_LEFT : 
-                                       mouse_left_button_up(event, mouse_over);
+                                       mouse_button_up(event, mouse_over, 
left_);
+                                       break;
+                               case SDL_BUTTON_MIDDLE :
+                                       mouse_button_up(event, mouse_over, 
middle_);
+                                       break;
+                               case SDL_BUTTON_RIGHT :
+                                       mouse_button_up(event, mouse_over, 
right_);
                                        break;
                                default:
                                        // cast to avoid being printed as char.
                                        WRN_G_E << "Unhandled 'mouse button up' 
event for button " 
                                                << 
static_cast<Uint32>(event.button.button) << ".\n";
+                                       assert(false);
                                        break;
                        }
                        break;
@@ -333,18 +359,19 @@
        mouse_focus_ = 0;
 }
 
-void tevent_handler::mouse_left_button_down(const SDL_Event& /*event*/, 
twidget* mouse_over)
-{
-       if(mouse_left_button_down_) {
-               WRN_G_E << "In 'left button down' but the mouse "
-                       << "button is already down, we missed an event.\n";
-               return;
-       }
-       mouse_left_button_down_ = true;
+void tevent_handler::mouse_button_down(const SDL_Event& event, twidget* 
mouse_over, tmouse_button& button)
+{
+       if(button.is_down) {
+               WRN_G_E << "In 'button down' for button '" << button.name 
+                       << "' but the mouse button is already down, we missed 
an event.\n";
+               return;
+       }
+       button.is_down = true;
        hover_pending_ = false;
 
        if(mouse_captured_) {
-               mouse_focus_->mouse_left_button_down(*this);
+               button.focus = mouse_focus_;
+               (mouse_focus_->*button.down)(*this);
        } else {
                if(!mouse_over) {
                        return;
@@ -355,50 +382,28 @@
                                << "and mouse not captured, we missed 
events.\n";
                }
 
-               mouse_over->mouse_left_button_down(*this);
-       }
-}
-
-void tevent_handler::mouse_left_click(twidget* widget)
-{
-       if(widget->wants_mouse_left_double_click()) {
-               Uint32 stamp = SDL_GetTicks();
-               if(last_left_click_ + 500 >= stamp) { // FIXME 500 should be 
variable
-
-                       widget->mouse_left_button_double_click(*this);
-                       last_left_click_ = 0;
-
-               } else {
-
-                       widget->mouse_left_button_click(*this);
-                       last_left_click_ = stamp;
-               }
-
-       } else {
-       
-               widget->mouse_left_button_click(*this);
-       }
-
-}
-
-void tevent_handler::mouse_left_button_up(const SDL_Event& event, twidget* 
mouse_over)
-{
-       if(!mouse_left_button_down_) {
-               WRN_G_E << "In 'left button up' but the mouse "
-                       << "button is already up, we missed an event.\n";
-               return;
-       }
-
-       mouse_left_button_down_ = false;
-       if(!mouse_focus_) {
-               return;
-       }
-       mouse_focus_->mouse_left_button_up(*this);
+               button.focus = mouse_over;
+               (mouse_over->*button.down)(*this);
+       }
+}
+
+void tevent_handler::mouse_button_up(const SDL_Event& event, twidget* 
mouse_over, tmouse_button& button)
+{
+       if(!button.is_down) {
+               WRN_G_E << "In 'button up' for button '" << button.name 
+                       << "' but the mouse button is already up, we missed an 
event.\n";
+               return;
+       }
+
+       button.is_down = false;
+       if(button.focus) {
+               (button.focus->*button.up)(*this);
+       }
 
        if(mouse_captured_) {
 
                if(mouse_focus_ != mouse_over) {
-                       if (!mouse_middle_button_down_ && 
!mouse_right_button_down_) {
+                       if (!left_.is_down && !middle_.is_down && 
!right_.is_down) {
                                mouse_captured_ = false;
 
                                mouse_leave(event, mouse_over);
@@ -408,13 +413,35 @@
                                }
                        }
                } else {
-                       mouse_left_click(mouse_focus_);
+                       mouse_click(mouse_focus_, button);
                }
+       } else if(button.focus && button.focus == mouse_over) {
+               mouse_click(button.focus, button);
+       }
+
+       button.focus = 0;
+       set_hover();
+}
+
+void tevent_handler::mouse_click(twidget* widget, tmouse_button& button)
+{
+       if((widget->*button.wants_double_click)()) {
+               Uint32 stamp = SDL_GetTicks();
+               if(button.last_click_stamp + 500 >= stamp) { // FIXME 500 
should be variable
+
+                       (widget->*button.double_click)(*this);
+                       button.last_click_stamp = 0;
+
+               } else {
+
+                       (widget->*button.click)(*this);
+                       button.last_click_stamp = stamp;
+               }
+
        } else {
-               mouse_left_click(mouse_over);
-       }
-
-       set_hover();
+       
+               widget->mouse_left_button_click(*this);
+       }
 }
 
 void tevent_handler::set_hover(const bool test_on_widget)
@@ -435,7 +462,7 @@
        }
 
        // Mouse down, no hovering
-       if(mouse_left_button_down_ || mouse_middle_button_down_ || 
mouse_right_button_down_) {
+       if(left_.is_down || middle_.is_down || right_.is_down) {
                return;
        } 
 
@@ -609,7 +636,7 @@
  * |              |              
  * |              V
  * |     --------------------        -------------------- 
- * |    | moves on widget    | -->  / fire mouse move  /
+ * |    | moves on widget    | -->  / fire mouse move   /
  * |     --------------------      ---------------------
  * |                                        |
  * |               --------------------------------------------------

Modified: trunk/src/gui/widgets/event_handler.hpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/gui/widgets/event_handler.hpp?rev=26162&r1=26161&r2=26162&view=diff
==============================================================================
--- trunk/src/gui/widgets/event_handler.hpp (original)
+++ trunk/src/gui/widgets/event_handler.hpp Sun Apr 27 10:08:36 2008
@@ -20,6 +20,7 @@
 
 #include "events.hpp"
 #include "gui/widgets/helper.hpp"
+#include "gui/widgets/widget.hpp"
 
 #include "SDL.h"
 
@@ -27,7 +28,6 @@
 
 namespace gui2{
 
-class twidget;
 class twindow;
 
 class tevent_handler : public events::handler
@@ -60,6 +60,50 @@
        void remove_help_popup();
 
 private:
+
+       struct tmouse_button {
+               
+               tmouse_button(const std::string& name, 
+                       void (tevent_executor::*down) (tevent_handler&),
+                       void (tevent_executor::*up) (tevent_handler&),
+                       void (tevent_executor::*click) (tevent_handler&),
+                       void (tevent_executor::*double_click) (tevent_handler&),
+                       bool (tevent_executor::*wants_double_click) () const) :
+                               last_click_stamp(0),
+                               focus(0),
+                               name(name),
+                               down(down),
+                               up(up),
+                               click(click),
+                               double_click(double_click),
+                               wants_double_click(wants_double_click),
+                               is_down(false)
+                       {}
+
+               //! The time of the last click used for double clicking.
+               Uint32 last_click_stamp;
+
+               //! If the mouse isn't captured we need to verify the up
+               //! is on the same widget as the down so we send a proper
+               //! click, also needed to send the up to the right widget.
+               twidget* focus;
+
+               //! used for debug messages.
+               const std::string name;
+
+               //! Pointers to member functions, this way we can call the 
proper
+               //! function indirect without writing a case for which button to
+               //! use.
+               void (tevent_executor::*down) (tevent_handler&);
+               void (tevent_executor::*up) (tevent_handler&);
+               void (tevent_executor::*click) (tevent_handler&);
+               void (tevent_executor::*double_click) (tevent_handler&);
+               bool (tevent_executor::*wants_double_click) () const;
+
+               //! Is the button down?
+               bool is_down;
+       };
+
        //! we create a new event context so we're always modal.
        //! Maybe this has to change, but not sure yet.
        events::event_context event_context_;
@@ -67,13 +111,9 @@
        int mouse_x_;                      //! The current mouse x.
        int mouse_y_;                      //! The current mouse y.
 
-       bool mouse_left_button_down_;      //! Is the left mouse button down?
-       bool mouse_middle_button_down_;    //! Is the middle mouse button down?
-       bool mouse_right_button_down_;     //! Is the right mouse button down?
-
-       Uint32 last_left_click_;        
-       Uint32 last_middle_click_;      
-       Uint32 last_right_click_;       
+       tmouse_button left_;
+       tmouse_button middle_;
+       tmouse_button right_;
 
        bool hover_pending_;                       //! Is there a hover event 
pending?
        unsigned hover_id_;                //! Id of the pending hover event.
@@ -97,9 +137,9 @@
        void mouse_leave(const SDL_Event& event, twidget* mouse_over);
 
 
-       void mouse_left_button_down(const SDL_Event& event, twidget* 
mouse_over);
-       void mouse_left_button_up(const SDL_Event& event, twidget* mouse_over);
-       void mouse_left_click(twidget* widget);
+       void mouse_button_down(const SDL_Event& event, twidget* mouse_over, 
tmouse_button& button);
+       void mouse_button_up(const SDL_Event& event, twidget* mouse_over, 
tmouse_button& button);
+       void mouse_click(twidget* widget, tmouse_button& button);
 
        void set_hover(const bool test_on_widget = false);
 

Modified: trunk/src/gui/widgets/text.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/gui/widgets/text.cpp?rev=26162&r1=26161&r2=26162&view=diff
==============================================================================
--- trunk/src/gui/widgets/text.cpp (original)
+++ trunk/src/gui/widgets/text.cpp Sun Apr 27 10:08:36 2008
@@ -15,6 +15,7 @@
 #include "gui/widgets/text.hpp"
 
 #include "clipboard.hpp"
+#include "gui/widgets/event_handler.hpp"
 #include "log.hpp"
 #include "serialization/string_utils.hpp"
 

Modified: trunk/src/gui/widgets/text_box.cpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/gui/widgets/text_box.cpp?rev=26162&r1=26161&r2=26162&view=diff
==============================================================================
--- trunk/src/gui/widgets/text_box.cpp (original)
+++ trunk/src/gui/widgets/text_box.cpp Sun Apr 27 10:08:36 2008
@@ -16,6 +16,7 @@
 
 #include "font.hpp"
 #include "foreach.hpp"
+#include "gui/widgets/event_handler.hpp"
 #include "log.hpp"
 #include "serialization/string_utils.hpp"
 #include "game_preferences.hpp"
@@ -224,10 +225,6 @@
 //! Inherited from twidget.
 void ttext_box::mouse_left_button_up(tevent_handler& event)
 {
-       // FIXME there's a bug in the event code if the up occurs
-       // off widget we aren't fired (which should happen).
-       // No work arounds made need to fix the event code.
-       
        DBG_G_E << "Text box: left mouse up.\n";
 
        dragging_ = false;

Modified: trunk/src/gui/widgets/widget.hpp
URL: 
http://svn.gna.org/viewcvs/wesnoth/trunk/src/gui/widgets/widget.hpp?rev=26162&r1=26161&r2=26162&view=diff
==============================================================================
--- trunk/src/gui/widgets/widget.hpp (original)
+++ trunk/src/gui/widgets/widget.hpp Sun Apr 27 10:08:36 2008
@@ -15,7 +15,6 @@
 #ifndef __GUI_WIDGETS_WIDGET_HPP_INCLUDED__
 #define __GUI_WIDGETS_WIDGET_HPP_INCLUDED__
 
-#include "gui/widgets/event_handler.hpp"
 #include "gui/widgets/helper.hpp"
 #include "sdl_utils.hpp"
 
@@ -23,8 +22,9 @@
 
 #include <string>
 
-
 namespace gui2 {
+
+class tevent_handler;
 
 //! Base class with all possible events, most widgets can ignore most of
 //! these, but they are available.


_______________________________________________
Wesnoth-commits mailing list
[email protected]
https://mail.gna.org/listinfo/wesnoth-commits

Reply via email to