00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016 #ifndef GUI_WIDGETS_AUXILIARY_EVENT_DISPATCHER_PRIVATE_HPP_INCLUDED
00017 #define GUI_WIDGETS_AUXILIARY_EVENT_DISPATCHER_PRIVATE_HPP_INCLUDED
00018
00019 #include "gui/auxiliary/event/dispatcher.hpp"
00020
00021 #include "gui/widgets/widget.hpp"
00022
00023 #include <boost/mpl/for_each.hpp>
00024
00025 namespace gui2 {
00026
00027 namespace event {
00028
00029 struct tdispatcher_implementation
00030 {
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #define IMPLEMENT_EVENT_SIGNAL(SET, FUNCTION, QUEUE) \
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058 \
00059 template<class F> \
00060 static typename boost::enable_if< \
00061 boost::is_same<F, FUNCTION> \
00062 , tdispatcher::tsignal<FUNCTION> \
00063 >::type& \
00064 event_signal(tdispatcher& dispatcher, const tevent event) \
00065 { \
00066 return dispatcher.QUEUE.queue[event]; \
00067 } \
00068 \
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081 \
00082 template<class K> \
00083 static typename boost::enable_if< \
00084 boost::mpl::has_key<SET, K> \
00085 , tdispatcher::tsignal<FUNCTION> \
00086 >::type& \
00087 event_signal(tdispatcher& dispatcher, const tevent event) \
00088 { \
00089 return dispatcher.QUEUE.queue[event]; \
00090 } \
00091
00092
00093 IMPLEMENT_EVENT_SIGNAL(tset_event, tsignal_function, signal_queue_)
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104 #define IMPLEMENT_EVENT_SIGNAL_WRAPPER(TYPE) \
00105 IMPLEMENT_EVENT_SIGNAL(tset_event_##TYPE \
00106 , tsignal_##TYPE##_function \
00107 , signal_##TYPE##_queue_) \
00108
00109 IMPLEMENT_EVENT_SIGNAL_WRAPPER(mouse)
00110 IMPLEMENT_EVENT_SIGNAL_WRAPPER(keyboard)
00111 IMPLEMENT_EVENT_SIGNAL_WRAPPER(notification)
00112 IMPLEMENT_EVENT_SIGNAL_WRAPPER(message)
00113
00114 #undef IMPLEMENT_EVENT_SIGNAL_WRAPPER
00115 #undef IMPLEMENT_EVENT_SIGNAL
00116
00117
00118
00119
00120
00121 class thas_handler
00122 {
00123 public:
00124
00125
00126
00127
00128
00129
00130 thas_handler(const tdispatcher::tevent_type event_type
00131 , tdispatcher& dispatcher)
00132 : event_type_(event_type)
00133 , dispatcher_(dispatcher)
00134 {}
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149 template<class T>
00150 bool oper(tevent event)
00151 {
00152 if((event_type_ & tdispatcher::pre)
00153 && !event_signal<T>(dispatcher_, event).pre_child.empty()) {
00154 return true;
00155 }
00156 if((event_type_ & tdispatcher::child)
00157 && !event_signal<T>(dispatcher_, event).child.empty()) {
00158 return true;
00159 }
00160 if((event_type_ & tdispatcher::post)
00161 && !event_signal<T>(dispatcher_, event).post_child.empty()){
00162 return true;
00163 }
00164 return false;
00165 }
00166
00167 private:
00168 tdispatcher::tevent_type event_type_;
00169 tdispatcher& dispatcher_;
00170 };
00171 };
00172
00173
00174 namespace implementation {
00175
00176
00177 template<bool done = true>
00178 struct find
00179 {
00180 template<
00181 typename itor
00182 , typename end
00183 , typename E
00184 , typename F
00185 >
00186 static bool execute(
00187 itor*
00188 , end*
00189 , E
00190 , F
00191 )
00192 {
00193 return false;
00194 }
00195 };
00196
00197
00198 template<>
00199 struct find<false>
00200 {
00201 template<
00202 typename itor
00203 , typename end
00204 , typename E
00205 , typename F
00206 >
00207 static bool execute(
00208 itor*
00209 , end*
00210 , E event
00211 , F functor
00212 )
00213 {
00214 typedef typename boost::mpl::deref<itor>::type item;
00215 typedef typename
00216 boost::mpl::apply1<boost::mpl::identity<>, item>::type arg;
00217
00218 boost::value_initialized<arg> x;
00219
00220 if(boost::get(x) == event) {
00221
00222 return functor.template oper<item>(event);
00223 } else {
00224 typedef typename boost::mpl::next<itor>::type titor;
00225 return find<boost::is_same<titor, end>::value>::execute(
00226 static_cast<titor*>(NULL)
00227 , static_cast<end*>(NULL)
00228 , event
00229 , functor);
00230 }
00231 }
00232 };
00233
00234 }
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254
00255
00256 template<
00257 typename sequence
00258 , typename E
00259 , typename F
00260 >
00261 inline bool find(E event, F functor)
00262 {
00263 typedef typename boost::mpl::begin<sequence>::type begin;
00264 typedef typename boost::mpl::end<sequence>::type end;
00265
00266 return implementation::find<boost::is_same<begin, end>::value>::execute(
00267 static_cast<begin*>(NULL)
00268 , static_cast<end*>(NULL)
00269 , event
00270 , functor);
00271 }
00272
00273 namespace implementation {
00274
00275
00276
00277
00278
00279
00280
00281
00282
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300
00301
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323 template<class T>
00324 inline std::vector<std::pair<twidget*, tevent> > build_event_chain(
00325 const tevent event
00326 , twidget* dispatcher
00327 , twidget* widget)
00328 {
00329 assert(dispatcher);
00330 assert(widget);
00331
00332 std::vector<std::pair<twidget*, tevent> > result;
00333
00334 while(widget != dispatcher) {
00335 widget = widget->parent();
00336 assert(widget);
00337
00338 if(widget->has_event(event, tdispatcher::tevent_type(
00339 tdispatcher::pre | tdispatcher::post))) {
00340
00341 result.push_back(std::make_pair(widget, event));
00342 }
00343 }
00344
00345 return result;
00346 }
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357 template<>
00358 inline std::vector<std::pair<twidget*, tevent> >
00359 build_event_chain<tsignal_notification_function>(
00360 const tevent event
00361 , twidget* dispatcher
00362 , twidget* widget)
00363 {
00364 assert(dispatcher);
00365 assert(widget);
00366
00367 assert(!widget->has_event(
00368 event
00369 , tdispatcher::tevent_type(
00370 tdispatcher::pre
00371 | tdispatcher::post)));
00372
00373 return std::vector<std::pair<twidget*, tevent> >();
00374 }
00375
00376 #ifdef _MSC_VER
00377 #pragma warning (push)
00378 #pragma warning (disable: 4706)
00379 #endif
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392
00393
00394
00395
00396
00397 template<>
00398 inline std::vector<std::pair<twidget*, tevent> >
00399 build_event_chain<tsignal_message_function>(
00400 const tevent event
00401 , twidget* dispatcher
00402 , twidget* widget)
00403 {
00404 assert(dispatcher);
00405 assert(widget);
00406 assert(widget == dispatcher);
00407
00408 std::vector<std::pair<twidget*, tevent> > result;
00409
00410
00411 while((widget = widget->parent())) {
00412 assert(widget);
00413
00414 if(widget->has_event(event, tdispatcher::tevent_type(
00415 tdispatcher::pre | tdispatcher::post))) {
00416
00417 result.insert(result.begin(), std::make_pair(widget, event));
00418 }
00419 }
00420
00421 return result;
00422 }
00423 #ifdef _MSC_VER
00424 #pragma warning (pop)
00425 #endif
00426
00427
00428
00429
00430
00431
00432
00433 template<class T, class F>
00434 inline bool fire_event(const tevent event
00435 , std::vector<std::pair<twidget*, tevent> >& event_chain
00436 , twidget* dispatcher
00437 , twidget* widget
00438 , F functor)
00439 {
00440 bool handled = false;
00441 bool halt = false;
00442
00443
00444 for(std::vector<std::pair<twidget*, tevent> >
00445 ::reverse_iterator ritor_widget = event_chain.rbegin();
00446 ritor_widget != event_chain.rend();
00447 ++ritor_widget) {
00448
00449 tdispatcher::tsignal<T>& signal = tdispatcher_implementation
00450 ::event_signal<T>(*ritor_widget->first, ritor_widget->second);
00451
00452 for(typename std::vector<T>::iterator itor = signal.pre_child.begin();
00453 itor != signal.pre_child.end();
00454 ++itor) {
00455
00456 functor(*itor, *dispatcher, ritor_widget->second, handled, halt);
00457 if(halt) {
00458 assert(handled);
00459 break;
00460 }
00461 }
00462
00463 if(handled) {
00464 return true;
00465 }
00466 }
00467
00468
00469 if(widget->has_event(event, tdispatcher::child)) {
00470
00471 tdispatcher::tsignal<T>& signal = tdispatcher_implementation
00472 ::event_signal<T>(*widget, event);
00473
00474 for(typename std::vector<T>::iterator itor = signal.child.begin();
00475 itor != signal.child.end();
00476 ++itor) {
00477
00478 functor(*itor, *dispatcher, event, handled, halt);
00479
00480 if(halt) {
00481 assert(handled);
00482 break;
00483 }
00484 }
00485
00486 if(handled) {
00487 return true;
00488 }
00489 }
00490
00491
00492 for(std::vector<std::pair<twidget*, tevent> >
00493 ::iterator itor_widget = event_chain.begin();
00494 itor_widget != event_chain.end();
00495 ++itor_widget) {
00496
00497 tdispatcher::tsignal<T>& signal = tdispatcher_implementation
00498 ::event_signal<T>(*itor_widget->first, itor_widget->second);
00499
00500 for(typename std::vector<T>::iterator itor = signal.post_child.begin();
00501 itor != signal.post_child.end();
00502 ++itor) {
00503
00504 functor(*itor, *dispatcher, itor_widget->second, handled, halt);
00505 if(halt) {
00506 assert(handled);
00507 break;
00508 }
00509 }
00510
00511 if(handled) {
00512 return true;
00513 }
00514 }
00515
00516
00517 assert(handled == false);
00518 return false;
00519 }
00520
00521 }
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546 template<class T, class F>
00547 inline bool fire_event(const tevent event
00548 , twidget* dispatcher
00549 , twidget* widget
00550 , F functor)
00551 {
00552 assert(dispatcher);
00553 assert(widget);
00554
00555 std::vector<std::pair<twidget*, tevent> > event_chain =
00556 implementation::build_event_chain<T>(event, dispatcher, widget);
00557
00558 return implementation::fire_event<T>(event
00559 , event_chain
00560 , dispatcher
00561 , widget
00562 , functor);
00563 }
00564
00565 template<
00566 tevent click
00567 , tevent double_click
00568 , bool(tevent_executor::*wants_double_click) () const
00569 , class T
00570 , class F
00571 >
00572 inline bool fire_event_double_click(
00573 twidget* dispatcher
00574 , twidget* widget
00575 , F functor)
00576 {
00577 assert(dispatcher);
00578 assert(widget);
00579
00580 std::vector<std::pair<twidget*, tevent> > event_chain;
00581 twidget* w = widget;
00582 while(w!= dispatcher) {
00583 w = w->parent();
00584 assert(w);
00585
00586 if((w->*wants_double_click)()) {
00587
00588 if(w->has_event(double_click, tdispatcher::tevent_type(
00589 tdispatcher::pre | tdispatcher::post))) {
00590
00591 event_chain.push_back(std::make_pair(w, double_click));
00592 }
00593 } else {
00594 if(w->has_event(click, tdispatcher::tevent_type(
00595 tdispatcher::pre | tdispatcher::post))) {
00596
00597 event_chain.push_back(std::make_pair(w, click));
00598 }
00599 }
00600 }
00601
00602 if((widget->*wants_double_click)()) {
00603 return implementation::fire_event<T>(double_click
00604 , event_chain
00605 , dispatcher
00606 , widget
00607 , functor);
00608 } else {
00609 return implementation::fire_event<T>(click
00610 , event_chain
00611 , dispatcher
00612 , widget
00613 , functor);
00614 }
00615 }
00616
00617 }
00618
00619 }
00620
00621 #endif
00622