gui/auxiliary/event/distributor.hpp

Go to the documentation of this file.
00001 /* $Id: distributor.hpp 52533 2012-01-07 02:35:17Z shadowmaster $ */
00002 /*
00003    Copyright (C) 2009 - 2012 by Mark de Wever <koraq@xs4all.nl>
00004    Part of the Battle for Wesnoth Project http://www.wesnoth.org/
00005 
00006    This program is free software; you can redistribute it and/or modify
00007    it under the terms of the GNU General Public License as published by
00008    the Free Software Foundation; either version 2 of the License, or
00009    (at your option) any later version.
00010    This program is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY.
00012 
00013    See the COPYING file for more details.
00014 */
00015 
00016 #ifndef GUI_WIDGETS_AUXILIARY_EVENT_DISTRIBUTOR_HPP_INCLUDED
00017 #define GUI_WIDGETS_AUXILIARY_EVENT_DISTRIBUTOR_HPP_INCLUDED
00018 
00019 /**
00020  * @file
00021  * Contains the event distributor.
00022  *
00023  * The event distributor exists of several classes which are combined in one
00024  * templated tdistributor class. The classes are closly tight together.
00025  *
00026  * All classes have direct access to eachothers members since they should act
00027  * as one. (Since the buttons are a templated subclass it's not possible to use
00028  * private subclasses.)
00029  *
00030  * The tmouse_motion class handles the mouse motion and holds the owner of us
00031  * since all classes virtually inherit us.
00032  *
00033  * The tmouse_button classes are templated classes per mouse button, the
00034  * template parameters are used to make the difference between the mouse
00035  * buttons. Althought it's easily possible to add more mouse buttons in the
00036  * code several places only expect a left, middle and right button.
00037  *
00038  * tdistributor is the main class to be used in the user code. This class
00039  * contains the handling of the keyboard as well.
00040  */
00041 
00042 #include "gui/auxiliary/event/dispatcher.hpp"
00043 #include "gui/widgets/event_executor.hpp"
00044 #include "gui/widgets/helper.hpp"
00045 
00046 namespace gui2{
00047 
00048 class twidget;
00049 
00050 namespace event {
00051 
00052 /***** ***** ***** ***** tmouse_motion ***** ***** ***** ***** *****/
00053 
00054 class tmouse_motion
00055 {
00056 public:
00057 
00058     tmouse_motion(twidget& owner, const tdispatcher::tposition queue_position);
00059 
00060     ~tmouse_motion();
00061 
00062     /**
00063      * Captures the mouse input.
00064      *
00065      * When capturing the widget that has the mouse focus_ does the capturing.
00066      *
00067      * @param capture             Set or release the capturing.
00068      */
00069     void capture_mouse(//twidget* widget);
00070             const bool capture = true);
00071 protected:
00072 
00073     /** The widget that currently has the mouse focus_. */
00074     twidget* mouse_focus_;
00075 
00076     /** Did the current widget capture the focus_? */
00077     bool mouse_captured_;
00078 
00079     /** The widget that owns us. */
00080     twidget& owner_;
00081 
00082     /** The timer for the hover event. */
00083     unsigned long hover_timer_;
00084 
00085     /** The widget which should get the hover event. */
00086     twidget* hover_widget_;
00087 
00088     /** The anchor point of the hover event. */
00089     tpoint hover_position_;
00090 
00091     /**
00092      * Has the hover been shown for the widget?
00093      *
00094      * A widget won't get a second hover event after the tooltip has been
00095      * triggered. Only after (shortly) entering another widget it will be shown
00096      * again for this widget.
00097      */
00098     bool hover_shown_;
00099 
00100     /**
00101      * Starts the hover timer.
00102      *
00103      * @param widget                 The widget that wants the tooltip.
00104      * @param coordinate             The anchor coordinate.
00105      */
00106     void start_hover_timer(twidget* widget, const tpoint& coordinate);
00107 
00108     /** Stops the current hover timer. */
00109     void stop_hover_timer();
00110 
00111     /**
00112      * Called when the mouse enters a widget.
00113      *
00114      * @param mouse_over          The widget that should receive the event.
00115      */
00116     void mouse_enter(twidget* mouse_over);
00117 
00118     /** Called when the mouse leaves the current widget. */
00119     void mouse_leave();
00120 
00121 private:
00122 
00123     /**
00124      * Called when the mouse moves over a widget.
00125      *
00126      * @param mouse_over          The widget that should receive the event.
00127      * @param coordinate          The current screen coordinate of the mouse.
00128      */
00129     void mouse_motion(twidget* mouse_over, const tpoint& coordinate);
00130 
00131     /** Called when the mouse wants the widget to show its tooltip. */
00132     void show_tooltip();
00133 
00134     bool signal_handler_sdl_mouse_motion_entered_;
00135     void signal_handler_sdl_mouse_motion(
00136               const event::tevent event
00137             , bool& handled
00138             , const tpoint& coordinate);
00139 
00140     void signal_handler_sdl_wheel(
00141               const event::tevent event
00142             , bool& handled
00143             , const tpoint& coordinate);
00144 
00145     void signal_handler_show_helptip(
00146               const event::tevent event
00147             , bool& handled
00148             , const tpoint& coordinate);
00149 };
00150 
00151 /***** ***** ***** ***** tmouse_button ***** ***** ***** ***** *****/
00152 
00153 template<
00154           tevent sdl_button_down
00155         , tevent sdl_button_up
00156         , tevent button_down
00157         , tevent button_up
00158         , tevent button_click
00159         , tevent button_double_click
00160 >
00161 class tmouse_button
00162     : public virtual tmouse_motion
00163 {
00164 public:
00165     tmouse_button(
00166               const std::string& name_
00167             , twidget& owner
00168             , const tdispatcher::tposition queue_position
00169             );
00170 
00171     /**
00172      * Initializes the state of the button.
00173      *
00174      * @param is_down             The initial state of the button, if true down
00175      *                            else initialized as up.
00176      */
00177     void initialize_state(const bool is_down);
00178 
00179 protected:
00180     /** The time of the last click used for double clicking. */
00181     Uint32 last_click_stamp_;
00182 
00183     /** The widget the last click was on, used for double clicking. */
00184     twidget* last_clicked_widget_;
00185 
00186     /**
00187      * If the mouse isn't captured we need to verify the up is on the same
00188      * widget as the down so we send a proper click, also needed to send the
00189      * up to the right widget.
00190      */
00191     twidget* focus_;
00192 
00193 private:
00194     /** used for debug messages. */
00195     const std::string name_;
00196 
00197     /** Is the button down? */
00198     bool is_down_;
00199 
00200     bool signal_handler_sdl_button_down_entered_;
00201     void signal_handler_sdl_button_down(
00202           const event::tevent event
00203         , bool& handled
00204         , const tpoint& coordinate);
00205 
00206     bool signal_handler_sdl_button_up_entered_;
00207     void signal_handler_sdl_button_up(
00208           const event::tevent event
00209         , bool& handled
00210         , const tpoint& coordinate);
00211 
00212 
00213     void mouse_button_click(twidget* widget);
00214 };
00215 
00216 /***** ***** ***** ***** tdistributor ***** ***** ***** ***** *****/
00217 
00218 typedef tmouse_button<
00219           SDL_LEFT_BUTTON_DOWN
00220         , SDL_LEFT_BUTTON_UP
00221         , LEFT_BUTTON_DOWN
00222         , LEFT_BUTTON_UP
00223         , LEFT_BUTTON_CLICK
00224         , LEFT_BUTTON_DOUBLE_CLICK
00225         > tmouse_button_left;
00226 
00227 typedef tmouse_button<
00228           SDL_MIDDLE_BUTTON_DOWN
00229         , SDL_MIDDLE_BUTTON_UP
00230         , MIDDLE_BUTTON_DOWN
00231         , MIDDLE_BUTTON_UP
00232         , MIDDLE_BUTTON_CLICK
00233         , MIDDLE_BUTTON_DOUBLE_CLICK
00234         > tmouse_button_middle;
00235 
00236 typedef tmouse_button<
00237           SDL_RIGHT_BUTTON_DOWN
00238         , SDL_RIGHT_BUTTON_UP
00239         , RIGHT_BUTTON_DOWN
00240         , RIGHT_BUTTON_UP
00241         , RIGHT_BUTTON_CLICK
00242         , RIGHT_BUTTON_DOUBLE_CLICK
00243         > tmouse_button_right;
00244 
00245 
00246 /** The event handler class for the widget library. */
00247 class tdistributor
00248     : public tmouse_button_left
00249     , public tmouse_button_middle
00250     , public tmouse_button_right
00251 {
00252 public:
00253     tdistributor(twidget& owner
00254             , const tdispatcher::tposition queue_position);
00255 
00256     ~tdistributor();
00257 
00258     /**
00259      * Initializes the state of the keyboard and mouse.
00260      *
00261      * Needed after initialization and reactivation.
00262      */
00263     void initialize_state();
00264 
00265     /**
00266      * Captures the keyboard input.
00267      *
00268      * @param widget              The widget which should capture the keyboard.
00269      *                            Sending NULL releases the capturing.
00270      */
00271     void keyboard_capture(twidget* widget);
00272 
00273     /**
00274      * Adds the widget to the keyboard chain.
00275      *
00276      * @param widget              The widget to add to the chain. The widget
00277      *                            should be valid widget, which hasn't been
00278      *                            added to the chain yet.
00279      */
00280     void keyboard_add_to_chain(twidget* widget);
00281 
00282     /**
00283      * Remove the widget from the keyborad chain.
00284      *
00285      * @param widget              The widget to be removed from the chain.
00286      */
00287     void keyboard_remove_from_chain(twidget* widget);
00288 
00289 private:
00290 
00291     bool hover_pending_;               /**< Is there a hover event pending? */
00292     unsigned hover_id_;                /**< Id of the pending hover event. */
00293     SDL_Rect hover_box_;               /**< The area the mouse can move in,
00294                                         *   moving outside invalidates the
00295                                         *   pending hover event.
00296                                         */
00297 
00298     bool had_hover_;                   /**< A widget only gets one hover event
00299                                         *   per enter cycle.
00300                                         */
00301 
00302     /** The widget of the currently active tooltip. */
00303     twidget* tooltip_;
00304 
00305     /** The widget of the currently active help popup. */
00306     twidget* help_popup_;
00307 
00308     /** The widget that holds the keyboard focus_. */
00309     twidget* keyboard_focus_;
00310 
00311     /**
00312      * Fall back keyboard focus_ items.
00313      *
00314      * When the focussed widget didn't handle the keyboard event (or no handler
00315      * for the keyboard focus_) it is send all widgets in this vector. The order
00316      * is from rbegin() to rend().  If the keyboard_focus_ is in the vector it
00317      * won't get the event twice. The first item added to the vector should be
00318      * the window, so it will be the last handler and can dispatch the hotkeys
00319      * registered.
00320      */
00321     std::vector<twidget*> keyboard_focus_chain_;
00322 
00323     /**
00324      * Set of functions that handle certain events and sends them to the proper
00325      * widget. These functions are called by the SDL event handling functions.
00326      */
00327 
00328     void signal_handler_sdl_key_down(const SDLKey key
00329             , const SDLMod modifier
00330             , const Uint16 unicode);
00331 
00332     void signal_handler_notify_removal(tdispatcher& widget, const tevent event);
00333 };
00334 
00335 } // namespace event
00336 
00337 } // namespace gui2
00338 
00339 #endif
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Generated by doxygen 1.7.1 on Thu May 24 2012 01:02:39 for The Battle for Wesnoth
Gna! | Forum | Wiki | CIA | devdocs