gui/auxiliary/event/dispatcher.hpp

Go to the documentation of this file.
00001 /* $Id: dispatcher.hpp 54265 2012-05-20 19:19:29Z mordante $ */
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_DISPATCHER_HPP_INCLUDED
00017 #define GUI_WIDGETS_AUXILIARY_EVENT_DISPATCHER_HPP_INCLUDED
00018 
00019 #include "gui/auxiliary/event/handler.hpp"
00020 #include "hotkeys.hpp"
00021 
00022 #include <boost/function.hpp>
00023 #include <boost/mpl/int.hpp>
00024 #include <boost/utility/enable_if.hpp>
00025 
00026 #include <map>
00027 
00028 namespace gui2 {
00029 
00030 struct tpoint;
00031 class twidget;
00032 
00033 namespace event {
00034 
00035 struct tmessage;
00036 
00037 /**
00038  * Callback function signature.
00039  *
00040  * There are several kinds of callback signature, this only has the parameters
00041  * shared by all callbacks.
00042  *
00043  * This function is used for the callbacks in tset_event.
00044  */
00045 typedef
00046         boost::function<void(
00047               tdispatcher& dispatcher
00048             , const tevent event
00049             , bool& handled
00050             , bool& halt)>
00051         tsignal_function;
00052 
00053 /**
00054  * Callback function signature.
00055  *
00056  * This function is used for the callbacks in tset_event_mouse.
00057  */
00058 typedef
00059         boost::function<void(
00060               tdispatcher& dispatcher
00061             , const tevent event
00062             , bool& handled
00063             , bool& halt
00064             , const tpoint& coordinate)>
00065         tsignal_mouse_function;
00066 
00067 /**
00068  * Callback function signature.
00069  *
00070  * This function is used for the callbacks in tset_event_keyboard.
00071  */
00072 typedef
00073         boost::function<void(
00074               tdispatcher& dispatcher
00075             , const tevent event
00076             , bool& handled
00077             , bool& halt
00078             , const SDLKey key
00079             , const SDLMod modifier
00080             , const Uint16 unicode) >
00081         tsignal_keyboard_function;
00082 
00083 /**
00084  * Callback function signature.
00085  *
00086  * This function is used for the callbacks in tset_event_notification.
00087  * Added the dummy void* parameter which will be NULL to get a different
00088  * signature as tsignal_function's callback.
00089  */
00090 typedef
00091         boost::function<void(
00092               tdispatcher& dispatcher
00093             , const tevent event
00094             , bool& handled
00095             , bool& halt
00096             , void*)>
00097         tsignal_notification_function;
00098 
00099 /**
00100  * Callback function signature.
00101  *
00102  * This function is used for the callbacks in tset_message_notification.
00103  */
00104 typedef
00105         boost::function<void(
00106               tdispatcher& dispatcher
00107             , const tevent event
00108             , bool& handled
00109             , bool& halt
00110             , tmessage& message)>
00111         tsignal_message_function;
00112 
00113 /** Hotkey function handler signature. */
00114 typedef
00115         boost::function<bool(
00116                   tdispatcher& dispatcher
00117                 , hotkey::HOTKEY_COMMAND id)>
00118         thotkey_function;
00119 
00120 /**
00121  * Base class for event handling.
00122  *
00123  * A dispatcher has slots for events, when an event arrives it looks for the
00124  * functions that registered themselves for that event and calls their
00125  * callbacks.
00126  *
00127  * This class is a base class for all widgets[1], what a widget does on a
00128  * callback can differ greatly, an image might ignore all events a window can
00129  * track the mouse location and fire MOUSE_ENTER and MOUSE_LEAVE events to the
00130  * widgets involved.
00131  *
00132  * [1] Not really sure whether it will be a base clase for a twidget or
00133  * tcontrol yet.
00134  */
00135 class tdispatcher
00136 {
00137     friend struct tdispatcher_implementation;
00138 public:
00139     tdispatcher();
00140     virtual ~tdispatcher();
00141 
00142     /**
00143      * Connects the dispatcher to the event handler.
00144      *
00145      * When a dispatcher is connected to the event handler it will get the
00146      * events directly from the event handler. This is wanted for top level
00147      * items like windows but not for most other widgets.
00148      *
00149      * So a window can call connect to register itself, it will automatically
00150      * disconnect upon destruction.
00151      */
00152     void connect();
00153 
00154     /**
00155      * Determines whether the location is inside an active widget.
00156      *
00157      * This is used to see whether a mouse event is inside the widget.
00158      *
00159      * @param coordinate             The coordinate to test whether inside the
00160      *                               widget.
00161      *
00162      * @result                       True if inside an active widget, false
00163      *                               otherwise.
00164      */
00165     virtual bool is_at(const tpoint& coordinate) const = 0;
00166 
00167     enum tevent_type
00168     {
00169           pre   = 1
00170         , child = 2
00171         , post  = 4
00172     };
00173 
00174     bool has_event(const tevent event, const tevent_type event_type);
00175 
00176     /** Fires an event which has no extra parameters. */
00177     bool fire(const tevent event, twidget& target);
00178 
00179     /**
00180      * Fires an event which takes a coordinate parameter.
00181      *
00182      * @param event                  The event to fire.
00183      * @param target                 The widget that should receive the event.
00184      * @param coordinate             The mouse position for the event.
00185      */
00186     bool fire(const tevent event, twidget& target, const tpoint& coordinate);
00187 
00188     /**
00189      * Fires an event which takes keyboard parameters.
00190      *
00191      * @param event                  The event to fire.
00192      * @param target                 The widget that should receive the event.
00193      * @param key                    The SDL key code of the key pressed.
00194      * @param modifier               The SDL key modifiers used.
00195      * @param unicode                The unicode value for the key pressed.
00196      */
00197     bool fire(const tevent event
00198             , twidget& target
00199             , const SDLKey key
00200             , const SDLMod modifier
00201             , const Uint16 unicode);
00202 
00203     /**
00204      * Fires an event which takes notification parameters.
00205      *
00206      * @note the void* parameter is a dummy needed for SFINAE.
00207      *
00208      * @param event                  The event to fire.
00209      * @param target                 The widget that should receive the event.
00210      */
00211     bool fire(const tevent event, twidget& target, void*);
00212 
00213     /**
00214      * Fires an event which takes message parameters.
00215      *
00216      * @param event                  The event to fire.
00217      * @param target                 The widget that should receive the event.
00218      *                               Normally this is the window holding the
00219      *                               widget.
00220      * @param message                The extra information needed for a window
00221      *                               (or another widget in the chain) to handle
00222      *                               the message.
00223      */
00224     bool fire(const tevent event, twidget& target, tmessage& message);
00225 
00226     /**
00227      * The position where to add a new callback in the signal handler.
00228      *
00229      * The signal handler has three callback queues:
00230      * * pre_child These callbacks are called before a container widget sends it
00231      *   to the child items. Widgets without children should also use this
00232      *   queue.
00233      * * child The callbacks for the proper child widget(s) are called.
00234      * * post_child The callbacks for the parent container to be called after
00235      *   the child.
00236      *
00237      * For every queue it's possible to add a new event in the front or in the
00238      * back.
00239      *
00240      * Whether all three queues are executed depend on the whether the
00241      * callbacks modify the handled and halt flag.
00242      * * When the halt flag is set execution of the current queue stops, when
00243      *   doing so the handled flag must be set as well.
00244      * * When the handled flag is set the events in that queue are executed and
00245      *   no more queues afterwards.
00246      *
00247      * Here are some use case examples.
00248      * A button that plays a sound and executes an optional user callback:
00249      * * The buttons internal click handler is invoked and sets the handled
00250      *   flag
00251      * * The callback installed by the user is in the same queue and gets
00252      *   exectuted afterwards.
00253      *
00254      * A toggle button may or may not be toggled:
00255      * * The user inserts a callback, that validates whether the action is
00256      *   allowed, if not allowed it sets the halt flag (and handled), else
00257      *   leaves the flags untouched.
00258      * * The normal buttons toggle function then might get invoked and if so
00259      *   sets the handled flag.
00260      * * Optionally there is another user callback invoked at this point.
00261      */
00262     enum tposition
00263     {
00264         front_pre_child,
00265         back_pre_child,
00266         front_child,
00267         back_child,
00268         front_post_child,
00269         back_post_child
00270     };
00271 
00272     /**
00273      * Connect a signal for callback in tset_event.
00274      *
00275      * The function uses some boost magic to avoid registering the wrong
00276      * function, but the common way to use this function is:
00277      * widget->connect_signal<EVENT_ID>(
00278      * boost::bind(&tmy_dialog::my_member, this));
00279      * This allows simply adding a member of a dialog to be used as a callback
00280      * for widget without a lot of magic. Note most widgets probaly will get a
00281      * callback like
00282      * connect_signal_mouse_left_click(const tsignal_function& callback)
00283      * which hides this function for the avarage use.
00284      *
00285      * @tparam E                     The event the callback needs to react to.
00286      * @param signal                 The callback function.
00287      * @param position               The position to place the callback.
00288      */
00289     template<tevent E>
00290     typename boost::enable_if<boost::mpl::has_key<
00291             tset_event, boost::mpl::int_<E> > >::type
00292     connect_signal(const tsignal_function& signal
00293             , const tposition position = back_child)
00294     {
00295         signal_queue_.connect_signal(E, position, signal);
00296     }
00297 
00298     /**
00299      * Disconnect a signal for callback in tset_event.
00300      *
00301      * @tparam E                     The event the callback was used for.
00302      * @param signal                 The callback function.
00303      * @param position               The place where the function was added.
00304      *                               Needed remove the event from the right
00305      *                               place. (The function doesn't care whether
00306      *                               was added in front or back.)
00307      */
00308     template<tevent E>
00309     typename boost::enable_if<boost::mpl::has_key<
00310             tset_event, boost::mpl::int_<E> > >::type
00311     disconnect_signal(const tsignal_function& signal
00312             , const tposition position = back_child)
00313     {
00314         signal_queue_.disconnect_signal(E, position, signal);
00315     }
00316 
00317     /**
00318      * Connect a signal for callback in tset_event_mouse.
00319      *
00320      * @tparam E                     The event the callback needs to react to.
00321      * @param signal                 The callback function.
00322      * @param position               The position to place the callback.
00323      */
00324     template<tevent E>
00325     typename boost::enable_if<boost::mpl::has_key<
00326             tset_event_mouse, boost::mpl::int_<E> > >::type
00327     connect_signal(const tsignal_mouse_function& signal
00328             , const tposition position = back_child)
00329     {
00330         signal_mouse_queue_.connect_signal(E, position, signal);
00331     }
00332 
00333     /**
00334      * Disconnect a signal for callback in tset_event_mouse.
00335      *
00336      * @tparam E                     The event the callback was used for.
00337      * @param signal                 The callback function.
00338      * @param position               The place where the function was added.
00339      *                               Needed remove the event from the right
00340      *                               place. (The function doesn't care whether
00341      *                               was added in front or back.)
00342      */
00343     template<tevent E>
00344     typename boost::enable_if<boost::mpl::has_key<
00345             tset_event_mouse, boost::mpl::int_<E> > >::type
00346     disconnect_signal(const tsignal_mouse_function& signal
00347             , const tposition position = back_child)
00348     {
00349         signal_mouse_queue_.disconnect_signal(E, position, signal);
00350     }
00351 
00352     /**
00353      * Connect a signal for callback in tset_event_keyboard.
00354      *
00355      * @tparam E                     The event the callback needs to react to.
00356      * @param signal                 The callback function.
00357      * @param position               The position to place the callback.
00358      */
00359     template<tevent E>
00360     typename boost::enable_if<boost::mpl::has_key<
00361             tset_event_keyboard, boost::mpl::int_<E> > >::type
00362     connect_signal(const tsignal_keyboard_function& signal
00363             , const tposition position = back_child)
00364     {
00365         signal_keyboard_queue_.connect_signal(E, position, signal);
00366     }
00367 
00368     /**
00369      * Disconnect a signal for callback in tset_event_keyboard.
00370      *
00371      * @tparam E                     The event the callback was used for.
00372      * @param signal                 The callback function.
00373      * @param position               The place where the function was added.
00374      *                               Needed remove the event from the right
00375      *                               place. (The function doesn't care whether
00376      *                               was added in front or back.)
00377      */
00378     template<tevent E>
00379     typename boost::enable_if<boost::mpl::has_key<
00380             tset_event_keyboard, boost::mpl::int_<E> > >::type
00381     disconnect_signal(const tsignal_keyboard_function& signal
00382             , const tposition position = back_child)
00383     {
00384         signal_keyboard_queue_.disconnect_signal(E, position, signal);
00385     }
00386 
00387     /**
00388      * Connect a signal for callback in tset_event_notification.
00389      *
00390      * @tparam E                     The event the callback needs to react to.
00391      * @param signal                 The callback function.
00392      * @param position               The position to place the callback. Since
00393      *                               the message is send to a widget directly
00394      *                               the pre and post positions make no sense
00395      *                               and shouldn't be used.
00396      */
00397     template<tevent E>
00398     typename boost::enable_if<boost::mpl::has_key<
00399             tset_event_notification, boost::mpl::int_<E> > >::type
00400     connect_signal(const tsignal_notification_function& signal
00401             , const tposition position = back_child)
00402     {
00403         signal_notification_queue_.connect_signal(E, position, signal);
00404     }
00405 
00406     /**
00407      * Disconnect a signal for callback in tset_event_notification.
00408      *
00409      * @tparam E                     The event the callback was used for.
00410      * @param signal                 The callback function.
00411      * @param position               The place where the function was added.
00412      *                               Needed remove the event from the right
00413      *                               place. (The function doesn't care whether
00414      *                               was added in front or back, but it needs
00415      *                               to know the proper queue so it's save to
00416      *                               add with front_child and remove with
00417      *                               back_child. But it's not save to add with
00418      *                               front_child and remove with
00419      *                               front_pre_child)
00420      */
00421     template<tevent E>
00422     typename boost::enable_if<boost::mpl::has_key<
00423             tset_event_notification, boost::mpl::int_<E> > >::type
00424     disconnect_signal(const tsignal_notification_function& signal
00425             , const tposition position = back_child)
00426     {
00427         signal_notification_queue_.disconnect_signal(E, position, signal);
00428     }
00429 
00430     /**
00431      * Connect a signal for callback in tset_event_message.
00432      *
00433      * @tparam E                     The event the callback needs to react to.
00434      * @param signal                 The callback function.
00435      * @param position               The position to place the callback. Since
00436      *                               the message is send to a widget directly
00437      *                               the pre and post positions make no sense
00438      *                               and shouldn't be used.
00439      */
00440     template<tevent E>
00441     typename boost::enable_if<boost::mpl::has_key<
00442             tset_event_message, boost::mpl::int_<E> > >::type
00443     connect_signal(const tsignal_message_function& signal
00444             , const tposition position = back_child)
00445     {
00446         signal_message_queue_.connect_signal(E, position, signal);
00447     }
00448 
00449     /**
00450      * Disconnect a signal for callback in tset_event_message.
00451      *
00452      * @tparam E                     The event the callback was used for.
00453      * @param signal                 The callback function.
00454      * @param position               The place where the function was added.
00455      *                               Needed remove the event from the right
00456      *                               place. (The function doesn't care whether
00457      *                               was added in front or back, but it needs
00458      *                               to know the proper queue so it's save to
00459      *                               add with front_child and remove with
00460      *                               back_child. But it's not save to add with
00461      *                               front_child and remove with
00462      *                               front_pre_child)
00463      */
00464     template<tevent E>
00465     typename boost::enable_if<boost::mpl::has_key<
00466             tset_event_message, boost::mpl::int_<E> > >::type
00467     disconnect_signal(const tsignal_message_function& signal
00468             , const tposition position = back_child)
00469     {
00470         signal_message_queue_.disconnect_signal(E, position, signal);
00471     }
00472 
00473     /**
00474      * The behaviour of the mouse events.
00475      *
00476      * Normally for mouse events there's first cheched whether a dispatcher has
00477      * captured the mouse if so it gets the event.
00478      * If not the dispatcher is searched from the back to the front in the
00479      * layers and it's behavious is checked.
00480      * * none The event is never send to the layer and goes on the the next
00481      *   layer. This is used for tooltips who might cover a button but a click
00482      *   on the tooltips should still click the button.
00483      * * all The event is always send to this layer and stops the search for a
00484      *   next layer.
00485      * * hit If the mouse is inside the dispatcher area the event is send and
00486      *   no longer searched further. If not inside tests the last layer.
00487      *
00488      * If after these tests no dispatcher is found the event is ignored.
00489      */
00490     enum tmouse_behaviour
00491     {
00492           all
00493         , hit
00494         , none
00495     };
00496 
00497     /** Captures the mouse. */
00498     void capture_mouse()
00499     {
00500         gui2::event::capture_mouse(this);
00501     }
00502 
00503     /** Releases the mouse capture. */
00504     void release_mouse()
00505     {
00506         gui2::event::release_mouse(this);
00507     }
00508 
00509     /***** ***** ***** setters/getters ***** ***** *****/
00510 
00511     void set_mouse_behaviour(const tmouse_behaviour mouse_behaviour)
00512     {
00513         mouse_behaviour_ = mouse_behaviour;
00514     }
00515 
00516     tmouse_behaviour get_mouse_behaviour() const
00517     {
00518         return mouse_behaviour_;
00519     }
00520 
00521     void set_want_keyboard_input(const bool want_keyboard_input)
00522     {
00523         want_keyboard_input_ = want_keyboard_input;
00524     }
00525 
00526     bool get_want_keyboard_input() const
00527     {
00528         return want_keyboard_input_;
00529     }
00530 
00531     /** Helper struct to generate the various signal types. */
00532     template<class T>
00533     struct tsignal
00534     {
00535         tsignal()
00536             : pre_child()
00537             , child()
00538             , post_child()
00539         {
00540         }
00541 
00542         std::vector<T> pre_child;
00543         std::vector<T> child;
00544         std::vector<T> post_child;
00545     };
00546 
00547     /** Helper struct to generate the various event queues. */
00548     template<class T>
00549     struct tsignal_queue
00550     {
00551         tsignal_queue()
00552             : queue()
00553         {
00554         }
00555 
00556         std::map<tevent, tsignal<T> > queue;
00557 
00558         void connect_signal(const tevent event
00559                 , const tposition position
00560                 , const T& signal)
00561         {
00562             switch(position) {
00563                 case front_pre_child :
00564                     queue[event].pre_child.insert(
00565                             queue[event].pre_child.begin(), signal);
00566                     break;
00567                 case back_pre_child :
00568                     queue[event].pre_child.push_back(signal);
00569                     break;
00570 
00571                 case front_child :
00572                     queue[event].child.insert(
00573                             queue[event].child.begin(), signal);
00574                     break;
00575                 case back_child :
00576                     queue[event].child.push_back(signal);
00577                     break;
00578 
00579                 case front_post_child :
00580                     queue[event].post_child.insert(
00581                             queue[event].post_child.begin(), signal);
00582                     break;
00583                 case back_post_child :
00584                     queue[event].post_child.push_back(signal);
00585                     break;
00586             }
00587 
00588         }
00589 
00590         void disconnect_signal(const tevent event
00591                 , const tposition position
00592                 , const T& signal)
00593         {
00594             /*
00595              * The function doesn't differentiate between front and back
00596              * position so fall down from front to back.
00597              */
00598             switch(position) {
00599                 case front_pre_child :
00600                 case back_pre_child : {
00601                         tsignal<T>& signal_queue = queue[event];
00602                         for(typename std::vector<T>::iterator itor =
00603                                     signal_queue.child.begin()
00604                                 ; itor != signal_queue.child.end()
00605                                 ; ++itor) {
00606 
00607                             if(signal.target_type() == itor->target_type()) {
00608                                 signal_queue.child.erase(itor);
00609                                 return;
00610                             }
00611                         }
00612                     }
00613                     break;
00614 
00615                 case front_child :
00616                 case back_child : {
00617                         tsignal<T>& signal_queue = queue[event];
00618                         for(typename std::vector<T>::iterator itor =
00619                                     signal_queue.child.begin()
00620                                 ; itor != signal_queue.child.end()
00621                                 ; ++itor) {
00622 
00623                             if(signal.target_type() == itor->target_type()) {
00624                                 signal_queue.child.erase(itor);
00625                                 return;
00626                             }
00627                         }
00628                     }
00629                     break;
00630 
00631                 case front_post_child :
00632                 case back_post_child : {
00633                         tsignal<T>& signal_queue = queue[event];
00634                         for(typename std::vector<T>::iterator itor =
00635                                     signal_queue.child.begin()
00636                                 ; itor != signal_queue.child.end()
00637                                 ; ++itor) {
00638 
00639                             if(signal.target_type() == itor->target_type()) {
00640                                 signal_queue.child.erase(itor);
00641                                 return;
00642                             }
00643                         }
00644                     }
00645                     break;
00646             }
00647         }
00648     };
00649 
00650     /**
00651      * Registers a hotkey.
00652      *
00653      * @todo add a static function register_global_hotkey.
00654      *
00655      * Once that's done execute_hotkey will first try to execute a global
00656      * hotkey and if that fails tries the hotkeys in this dispatcher.
00657      *
00658      * @param id                  The hotkey to register.
00659      * @param function            The callback function to call.
00660      */
00661     void register_hotkey(const hotkey::HOTKEY_COMMAND id
00662             , const thotkey_function& function);
00663 
00664     /**
00665      * Executes a hotkey.
00666      *
00667      * @param id                  The hotkey to execute.
00668      *
00669      * @returns                   true if the hotkey is handled, false
00670      *                            otherwise.
00671      */
00672     bool execute_hotkey(const hotkey::HOTKEY_COMMAND id);
00673 
00674 private:
00675 
00676     /** The mouse behaviour for the dispatcher. */
00677     tmouse_behaviour mouse_behaviour_;
00678 
00679     /**
00680      * Does the dispatcher want to receive keyboard input.
00681      *
00682      * @todo The entire mouse and keyboard handling can use a code review to
00683      * seen whether it might be combined in one flag field. At the moment the
00684      * keyboard doesn't look whether a dialog has the mouse focus before
00685      * sending the event, so maybe we should add an active dispatcher to keep
00686      * track of it. But since at the moment there are only non-modal windows
00687      * and tooltips it's not a problem.
00688      */
00689     bool want_keyboard_input_;
00690 
00691     /** Signal queue for callbacks in tset_event. */
00692     tsignal_queue<tsignal_function> signal_queue_;
00693 
00694     /** Signal queue for callbacks in tset_event_mouse. */
00695     tsignal_queue<tsignal_mouse_function> signal_mouse_queue_;
00696 
00697     /** Signal queue for callbacks in tset_event_keyboard. */
00698     tsignal_queue<tsignal_keyboard_function> signal_keyboard_queue_;
00699 
00700     /** Signal queue for callbacks in tset_event_notification. */
00701     tsignal_queue<tsignal_notification_function> signal_notification_queue_;
00702 
00703     /** Signal queue for callbacks in tset_event_message. */
00704     tsignal_queue<tsignal_message_function> signal_message_queue_;
00705 
00706     /** Are we connected to the event handler. */
00707     bool connected_;
00708 
00709     /** The registered hotkeys for this dispatcher. */
00710     std::map<hotkey::HOTKEY_COMMAND, thotkey_function> hotkeys_;
00711 };
00712 
00713 /***** ***** ***** ***** ***** Common helpers  ***** ***** ***** ***** *****/
00714 
00715 /*
00716  * These helpers can be used to easily add callbacks to a dispatcher (widget).
00717  * This is just a list of common ones all others can be used as well.
00718  */
00719 
00720 /**
00721  * Connects the signal for 'snooping' on the keypress.
00722  *
00723  * This callback is called before the widget itself allowing you to either
00724  * snoop on the input or filter it.
00725  */
00726 inline void connect_signal_pre_key_press(
00727           tdispatcher& dispatcher
00728         , const tsignal_keyboard_function& signal)
00729 {
00730     dispatcher.connect_signal<SDL_KEY_DOWN>(
00731               signal
00732             , tdispatcher::front_child);
00733 }
00734 
00735 /** Connects a signal handler for a left mouse button click. */
00736 inline void connect_signal_mouse_left_click(
00737           tdispatcher& dispatcher
00738         , const tsignal_function& signal)
00739 {
00740     dispatcher.connect_signal<LEFT_BUTTON_CLICK>(signal);
00741 }
00742 
00743 /** Disconnects a signal handler for a left mouse button click. */
00744 inline void disconnect_signal_mouse_left_click(
00745           tdispatcher& dispatcher
00746         , const tsignal_function& signal)
00747 {
00748     dispatcher.disconnect_signal<LEFT_BUTTON_CLICK>(signal);
00749 }
00750 
00751 /** Connects a signal handler for getting a notification upon modification. */
00752 inline void connect_signal_notify_modified(
00753           tdispatcher& dispatcher
00754         , const tsignal_notification_function& signal)
00755 {
00756     dispatcher.connect_signal<event::NOTIFY_MODIFIED>(signal);
00757 }
00758 
00759 } // namespace event
00760 
00761 } // namespace gui2
00762 
00763 #endif
00764 
 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