00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019 #include "mouseWatcher.h"
00020 #include "config_tform.h"
00021 #include "mouseWatcherParameter.h"
00022 #include "mouseAndKeyboard.h"
00023 #include "mouseData.h"
00024 #include "buttonEventList.h"
00025 #include "mouseButton.h"
00026 #include "throw_event.h"
00027 #include "eventParameter.h"
00028 #include "dataNodeTransmit.h"
00029 #include "transformState.h"
00030 #include "dcast.h"
00031
00032 #include <algorithm>
00033
00034 TypeHandle MouseWatcher::_type_handle;
00035
00036
00037
00038
00039
00040
00041 MouseWatcher::
00042 MouseWatcher(const string &name) :
00043 DataNode(name)
00044 {
00045 _pixel_xy_input = define_input("pixel_xy", EventStoreVec2::get_class_type());
00046 _xy_input = define_input("xy", EventStoreVec2::get_class_type());
00047 _button_events_input = define_input("button_events", ButtonEventList::get_class_type());
00048
00049 _pixel_xy_output = define_output("pixel_xy", EventStoreVec2::get_class_type());
00050 _xy_output = define_output("xy", EventStoreVec2::get_class_type());
00051 _button_events_output = define_output("button_events", ButtonEventList::get_class_type());
00052
00053 _pixel_xy = new EventStoreVec2(LPoint2f(0.0f, 0.0f));
00054 _xy = new EventStoreVec2(LPoint2f(0.0f, 0.0f));
00055 _button_events = new ButtonEventList;
00056
00057 _has_mouse = false;
00058 _suppress_flags = 0;
00059 _preferred_region = (MouseWatcherRegion *)NULL;
00060 _preferred_button_down_region = (MouseWatcherRegion *)NULL;
00061 _button_down = false;
00062 _eh = (EventHandler*)0L;
00063
00064
00065
00066
00067
00068 _enter_multiple = false;
00069
00070
00071
00072
00073 _implicit_click = false;
00074 }
00075
00076
00077
00078
00079
00080
00081 MouseWatcher::
00082 ~MouseWatcher() {
00083 }
00084
00085
00086
00087
00088
00089
00090
00091
00092 bool MouseWatcher::
00093 remove_region(MouseWatcherRegion *region) {
00094 remove_region_from(_current_regions, region);
00095 if (region == _preferred_region) {
00096 _preferred_region = (MouseWatcherRegion *)NULL;
00097 }
00098 if (region == _preferred_button_down_region) {
00099 _preferred_button_down_region = (MouseWatcherRegion *)NULL;
00100 }
00101
00102 return MouseWatcherGroup::remove_region(region);
00103 }
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 MouseWatcherRegion *MouseWatcher::
00115 get_over_region(const LPoint2f &pos) const {
00116 VRegions regions;
00117 get_over_regions(regions, pos);
00118 return get_preferred_region(regions);
00119 }
00120
00121
00122
00123
00124
00125
00126
00127 void MouseWatcher::
00128 output(ostream &out) const {
00129 DataNode::output(out);
00130
00131 int count = _regions.size();
00132 Groups::const_iterator gi;
00133 for (gi = _groups.begin(); gi != _groups.end(); ++gi) {
00134 MouseWatcherGroup *group = (*gi);
00135 count += group->_regions.size();
00136 }
00137
00138 out << " (" << count << " regions)";
00139 }
00140
00141
00142
00143
00144
00145
00146 void MouseWatcher::
00147 write(ostream &out, int indent_level) const {
00148 indent(out, indent_level)
00149 << "MouseWatcher " << get_name() << ":\n";
00150 Regions::const_iterator ri;
00151 for (ri = _regions.begin(); ri != _regions.end(); ++ri) {
00152 MouseWatcherRegion *region = (*ri);
00153 region->write(out, indent_level + 2);
00154 }
00155
00156 if (!_groups.empty()) {
00157 Groups::const_iterator gi;
00158 for (gi = _groups.begin(); gi != _groups.end(); ++gi) {
00159 MouseWatcherGroup *group = (*gi);
00160 indent(out, indent_level + 2)
00161 << "Subgroup:\n";
00162 for (ri = group->_regions.begin(); ri != group->_regions.end(); ++ri) {
00163 MouseWatcherRegion *region = (*ri);
00164 region->write(out, indent_level + 4);
00165 }
00166 }
00167 }
00168 }
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186 bool MouseWatcher::
00187 add_group(MouseWatcherGroup *group) {
00188
00189
00190
00191 PT(MouseWatcherGroup) pt = group;
00192 Groups::const_iterator gi =
00193 find(_groups.begin(), _groups.end(), pt);
00194 if (gi != _groups.end()) {
00195
00196 return false;
00197 }
00198
00199
00200 _groups.push_back(pt);
00201 return true;
00202 }
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212 bool MouseWatcher::
00213 remove_group(MouseWatcherGroup *group) {
00214 remove_regions_from(_current_regions, group);
00215 if (group->has_region(_preferred_region)) {
00216 _preferred_region = (MouseWatcherRegion *)NULL;
00217 }
00218 if (group->has_region(_preferred_button_down_region)) {
00219 _preferred_button_down_region = (MouseWatcherRegion *)NULL;
00220 }
00221
00222
00223 PT(MouseWatcherGroup) pt = group;
00224 Groups::iterator gi =
00225 find(_groups.begin(), _groups.end(), pt);
00226 if (gi != _groups.end()) {
00227
00228 _groups.erase(gi);
00229 return true;
00230 }
00231
00232
00233 return false;
00234 }
00235
00236
00237
00238
00239
00240
00241
00242
00243 void MouseWatcher::
00244 get_over_regions(MouseWatcher::VRegions ®ions, const LPoint2f &pos) const {
00245
00246 regions.clear();
00247
00248 Regions::const_iterator ri;
00249 for (ri = _regions.begin(); ri != _regions.end(); ++ri) {
00250 MouseWatcherRegion *region = (*ri);
00251 const LVecBase4f &frame = region->get_frame();
00252
00253 if (region->get_active() &&
00254 pos[0] >= frame[0] && pos[0] <= frame[1] &&
00255 pos[1] >= frame[2] && pos[1] <= frame[3]) {
00256
00257 regions.push_back(region);
00258 }
00259 }
00260
00261
00262 Groups::const_iterator gi;
00263 for (gi = _groups.begin(); gi != _groups.end(); ++gi) {
00264 MouseWatcherGroup *group = (*gi);
00265 for (ri = group->_regions.begin(); ri != group->_regions.end(); ++ri) {
00266 MouseWatcherRegion *region = (*ri);
00267 const LVecBase4f &frame = region->get_frame();
00268
00269 if (region->get_active() &&
00270 pos[0] >= frame[0] && pos[0] <= frame[1] &&
00271 pos[1] >= frame[2] && pos[1] <= frame[3]) {
00272
00273 regions.push_back(region);
00274 }
00275 }
00276 }
00277
00278
00279
00280
00281 sort(regions.begin(), regions.end());
00282 }
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292 MouseWatcherRegion *MouseWatcher::
00293 get_preferred_region(const MouseWatcher::VRegions ®ions) {
00294 if (regions.empty()) {
00295 return (MouseWatcherRegion *)NULL;
00296 }
00297
00298 VRegions::const_iterator ri;
00299 ri = regions.begin();
00300 MouseWatcherRegion *preferred = *ri;
00301 ++ri;
00302 while (ri != regions.end()) {
00303 MouseWatcherRegion *region = *ri;
00304
00305 if (*region < *preferred) {
00306 preferred = region;
00307 }
00308 ++ri;
00309 }
00310
00311 return preferred;
00312 }
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323 void MouseWatcher::
00324 set_current_regions(MouseWatcher::VRegions ®ions) {
00325
00326 MouseWatcherParameter param;
00327 param.set_modifier_buttons(_mods);
00328 param.set_mouse(_mouse);
00329
00330
00331 VRegions::const_iterator new_ri = regions.begin();
00332 VRegions::const_iterator old_ri = _current_regions.begin();
00333
00334
00335
00336 vector<MouseWatcherRegion *> new_regions;
00337
00338 bool any_changes = false;
00339 while (new_ri != regions.end() && old_ri != _current_regions.end()) {
00340 if ((*new_ri) < (*old_ri)) {
00341
00342 MouseWatcherRegion *new_region = (*new_ri);
00343 new_regions.push_back(new_region);
00344 any_changes = true;
00345 ++new_ri;
00346
00347 } else if ((*old_ri) < (*new_ri)) {
00348
00349 MouseWatcherRegion *old_region = (*old_ri);
00350 without_region(old_region, param);
00351 any_changes = true;
00352 ++old_ri;
00353
00354 } else {
00355
00356 ++new_ri;
00357 ++old_ri;
00358 }
00359 }
00360
00361 while (new_ri != regions.end()) {
00362
00363 MouseWatcherRegion *new_region = (*new_ri);
00364 new_regions.push_back(new_region);
00365 any_changes = true;
00366 ++new_ri;
00367 }
00368
00369 while (old_ri != _current_regions.end()) {
00370
00371 MouseWatcherRegion *old_region = (*old_ri);
00372 without_region(old_region, param);
00373 any_changes = true;
00374 ++old_ri;
00375 }
00376
00377 if (any_changes) {
00378
00379
00380 _current_regions.swap(regions);
00381
00382
00383 vector<MouseWatcherRegion *>::const_iterator ri;
00384 for (ri = new_regions.begin(); ri != new_regions.end(); ++ri) {
00385 MouseWatcherRegion *new_region = (*ri);
00386 within_region(new_region, param);
00387 }
00388 }
00389
00390 if (!_enter_multiple) {
00391
00392
00393
00394 MouseWatcherRegion *new_preferred_region =
00395 get_preferred_region(_current_regions);
00396
00397 if (_button_down && new_preferred_region != _preferred_button_down_region) {
00398
00399
00400 new_preferred_region = (MouseWatcherRegion *)NULL;
00401 }
00402
00403 if (new_preferred_region != _preferred_region) {
00404 if (_preferred_region != (MouseWatcherRegion *)NULL) {
00405 exit_region(_preferred_region, param);
00406 }
00407 _preferred_region = new_preferred_region;
00408 if (_preferred_region != (MouseWatcherRegion *)NULL) {
00409 enter_region(_preferred_region, param);
00410 }
00411 }
00412 }
00413 }
00414
00415
00416
00417
00418
00419
00420 void MouseWatcher::
00421 clear_current_regions() {
00422 if (!_current_regions.empty()) {
00423
00424 MouseWatcherParameter param;
00425 param.set_modifier_buttons(_mods);
00426 param.set_mouse(_mouse);
00427
00428 VRegions::const_iterator old_ri = _current_regions.begin();
00429
00430 while (old_ri != _current_regions.end()) {
00431
00432 MouseWatcherRegion *old_region = (*old_ri);
00433 old_region->exit(param);
00434 throw_event_pattern(_leave_pattern, old_region, ButtonHandle::none());
00435 ++old_ri;
00436 }
00437
00438 _current_regions.clear();
00439
00440 if (_preferred_region != (MouseWatcherRegion *)NULL) {
00441 _preferred_region->exit(param);
00442 throw_event_pattern(_leave_pattern, _preferred_region, ButtonHandle::none());
00443 _preferred_region = (MouseWatcherRegion *)NULL;
00444 }
00445 }
00446 }
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456 void MouseWatcher::
00457 intersect_regions(MouseWatcher::VRegions &result,
00458 const MouseWatcher::VRegions ®ions_a,
00459 const MouseWatcher::VRegions ®ions_b) {
00460
00461
00462
00463 VRegions temp;
00464
00465
00466 VRegions::const_iterator a_ri = regions_a.begin();
00467 VRegions::const_iterator b_ri = regions_b.begin();
00468
00469 while (a_ri != regions_a.end() && b_ri != regions_b.end()) {
00470 if ((*a_ri) < (*b_ri)) {
00471
00472 ++a_ri;
00473
00474 } else if ((*b_ri) < (*a_ri)) {
00475
00476 ++b_ri;
00477
00478 } else {
00479
00480 temp.push_back(*a_ri);
00481 ++a_ri;
00482 ++b_ri;
00483 }
00484 }
00485
00486
00487 result.swap(temp);
00488 }
00489
00490
00491
00492
00493
00494
00495
00496 void MouseWatcher::
00497 remove_region_from(MouseWatcher::VRegions ®ions,
00498 MouseWatcherRegion *region) {
00499 PT(MouseWatcherRegion) ptr = region;
00500 VRegions::iterator ri = lower_bound(regions.begin(), regions.end(), ptr);
00501 if (ri != regions.end() && (*ri) == ptr) {
00502
00503 regions.erase(ri);
00504 }
00505 }
00506
00507
00508
00509
00510
00511
00512
00513
00514 void MouseWatcher::
00515 remove_regions_from(MouseWatcher::VRegions ®ions,
00516 MouseWatcherGroup *group) {
00517
00518
00519 VRegions temp;
00520
00521 VRegions::const_iterator a_ri = regions.begin();
00522 MouseWatcherGroup::Regions::const_iterator b_ri = group->_regions.begin();
00523
00524 while (a_ri != regions.end() && b_ri != group->_regions.end()) {
00525 if ((*a_ri) < (*b_ri)) {
00526
00527 ++a_ri;
00528
00529 } else if ((*b_ri) < (*a_ri)) {
00530
00531 temp.push_back(*b_ri);
00532 ++b_ri;
00533
00534 } else {
00535
00536 ++a_ri;
00537 ++b_ri;
00538 }
00539 }
00540
00541
00542 regions.swap(temp);
00543 }
00544
00545
00546
00547
00548
00549
00550
00551 void MouseWatcher::
00552 throw_event_pattern(const string &pattern, const MouseWatcherRegion *region,
00553 const ButtonHandle &button) {
00554 if (pattern.empty()) {
00555 return;
00556 }
00557 #ifndef NDEBUG
00558 if (region != (MouseWatcherRegion *)NULL) {
00559 region->test_ref_count_integrity();
00560 }
00561 #endif
00562
00563 string button_name;
00564 if (button != ButtonHandle::none()) {
00565 if (!_mods.has_button(button)) {
00566
00567
00568 button_name = _mods.get_prefix();
00569 }
00570 button_name += button.get_name();
00571 }
00572
00573 string event;
00574 for (size_t p = 0; p < pattern.size(); ++p) {
00575 if (pattern[p] == '%') {
00576 string cmd = pattern.substr(p + 1, 1);
00577 p++;
00578 if (cmd == "r") {
00579 if (region != (MouseWatcherRegion *)NULL) {
00580 event += button_name;
00581 }
00582
00583 } else if (cmd == "b") {
00584 event += button.get_name();
00585
00586 } else {
00587 tform_cat.error()
00588 << "Invalid symbol in event_pattern: %" << cmd << "\n";
00589 }
00590 } else {
00591 event += pattern[p];
00592 }
00593 }
00594
00595 if (!event.empty()) {
00596 throw_event(event, EventParameter(region), EventParameter(button_name));
00597 if (_eh != (EventHandler*)0L)
00598 throw_event_directly(*_eh, event, EventParameter(region),
00599 EventParameter(button_name));
00600 }
00601 }
00602
00603
00604
00605
00606
00607
00608
00609 void MouseWatcher::
00610 press(ButtonHandle button) {
00611 MouseWatcherParameter param;
00612 param.set_button(button);
00613 param.set_modifier_buttons(_mods);
00614 param.set_mouse(_mouse);
00615
00616 if (MouseButton::is_mouse_button(button)) {
00617
00618
00619 if (!_button_down) {
00620 _preferred_button_down_region = _preferred_region;
00621 }
00622 _button_down = true;
00623
00624 if (_preferred_button_down_region != (MouseWatcherRegion *)NULL) {
00625 _preferred_button_down_region->press(param);
00626 throw_event_pattern(_button_down_pattern,
00627 _preferred_button_down_region, button);
00628 }
00629
00630 } else {
00631
00632
00633
00634 if (_preferred_region != (MouseWatcherRegion *)NULL) {
00635
00636
00637
00638 _preferred_region->press(param);
00639 }
00640
00641 if ((_suppress_flags & MouseWatcherRegion::SF_other_button) == 0) {
00642
00643
00644
00645 param.set_outside(true);
00646 global_keyboard_press(param);
00647 }
00648 }
00649 }
00650
00651
00652
00653
00654
00655
00656
00657 void MouseWatcher::
00658 release(ButtonHandle button) {
00659 MouseWatcherParameter param;
00660 param.set_button(button);
00661 param.set_modifier_buttons(_mods);
00662 param.set_mouse(_mouse);
00663
00664 if (MouseButton::is_mouse_button(button)) {
00665
00666
00667
00668
00669
00670
00671 if (_preferred_button_down_region != (MouseWatcherRegion *)NULL) {
00672 param.set_outside(_preferred_button_down_region != _preferred_region);
00673 _preferred_button_down_region->release(param);
00674 throw_event_pattern(_button_up_pattern,
00675 _preferred_button_down_region, button);
00676 }
00677
00678 _button_down = false;
00679 _preferred_button_down_region = (MouseWatcherRegion *)NULL;
00680
00681 } else {
00682
00683
00684
00685 if (_preferred_region != (MouseWatcherRegion *)NULL) {
00686 _preferred_region->release(param);
00687 }
00688
00689 param.set_outside(true);
00690 global_keyboard_release(param);
00691 }
00692 }
00693
00694
00695
00696
00697
00698
00699
00700 void MouseWatcher::
00701 keystroke(int keycode) {
00702 MouseWatcherParameter param;
00703 param.set_keycode(keycode);
00704 param.set_modifier_buttons(_mods);
00705 param.set_mouse(_mouse);
00706
00707
00708
00709
00710
00711
00712
00713 Regions::const_iterator ri;
00714 for (ri = _regions.begin(); ri != _regions.end(); ++ri) {
00715 MouseWatcherRegion *region = (*ri);
00716
00717 if (region->get_keyboard()) {
00718 param.set_outside(region != _preferred_region);
00719 region->keystroke(param);
00720 }
00721 }
00722
00723
00724 Groups::const_iterator gi;
00725 for (gi = _groups.begin(); gi != _groups.end(); ++gi) {
00726 MouseWatcherGroup *group = (*gi);
00727 for (ri = group->_regions.begin(); ri != group->_regions.end(); ++ri) {
00728 MouseWatcherRegion *region = (*ri);
00729
00730 if (region->get_keyboard()) {
00731 param.set_outside(region != _preferred_region);
00732 region->keystroke(param);
00733 }
00734 }
00735 }
00736 }
00737
00738
00739
00740
00741
00742
00743
00744
00745 void MouseWatcher::
00746 global_keyboard_press(const MouseWatcherParameter ¶m) {
00747 Regions::const_iterator ri;
00748 for (ri = _regions.begin(); ri != _regions.end(); ++ri) {
00749 MouseWatcherRegion *region = (*ri);
00750
00751 if (region != _preferred_region && region->get_keyboard()) {
00752 region->press(param);
00753 }
00754 }
00755
00756
00757 Groups::const_iterator gi;
00758 for (gi = _groups.begin(); gi != _groups.end(); ++gi) {
00759 MouseWatcherGroup *group = (*gi);
00760 for (ri = group->_regions.begin(); ri != group->_regions.end(); ++ri) {
00761 MouseWatcherRegion *region = (*ri);
00762
00763 if (region != _preferred_region && region->get_keyboard()) {
00764 region->press(param);
00765 }
00766 }
00767 }
00768 }
00769
00770
00771
00772
00773
00774
00775
00776 void MouseWatcher::
00777 global_keyboard_release(const MouseWatcherParameter ¶m) {
00778 Regions::const_iterator ri;
00779 for (ri = _regions.begin(); ri != _regions.end(); ++ri) {
00780 MouseWatcherRegion *region = (*ri);
00781
00782 if (region != _preferred_region && region->get_keyboard()) {
00783 region->release(param);
00784 }
00785 }
00786
00787
00788 Groups::const_iterator gi;
00789 for (gi = _groups.begin(); gi != _groups.end(); ++gi) {
00790 MouseWatcherGroup *group = (*gi);
00791 for (ri = group->_regions.begin(); ri != group->_regions.end(); ++ri) {
00792 MouseWatcherRegion *region = (*ri);
00793
00794 if (region != _preferred_region && region->get_keyboard()) {
00795 region->release(param);
00796 }
00797 }
00798 }
00799 }
00800
00801
00802
00803
00804
00805
00806
00807 void MouseWatcher::
00808 enter_region(MouseWatcherRegion *region, const MouseWatcherParameter ¶m) {
00809 region->enter(param);
00810 throw_event_pattern(_enter_pattern, region, ButtonHandle::none());
00811 if (_implicit_click) {
00812 MouseWatcherParameter param1(param);
00813 param1.set_button(MouseButton::one());
00814 region->press(param1);
00815 }
00816 }
00817
00818
00819
00820
00821
00822
00823
00824 void MouseWatcher::
00825 exit_region(MouseWatcherRegion *region, const MouseWatcherParameter ¶m) {
00826 if (_implicit_click) {
00827 MouseWatcherParameter param1(param);
00828 param1.set_button(MouseButton::one());
00829 region->release(param1);
00830 }
00831 region->exit(param);
00832 throw_event_pattern(_leave_pattern, region, ButtonHandle::none());
00833 }
00834
00835
00836
00837
00838
00839
00840
00841
00842
00843
00844
00845
00846
00847
00848 void MouseWatcher::
00849 do_transmit_data(const DataNodeTransmit &input, DataNodeTransmit &output) {
00850 if (!input.has_data(_xy_input)) {
00851
00852
00853 if (_has_mouse) {
00854
00855 if (!_geometry.is_null()) {
00856 _geometry->set_draw_mask(DrawMask::all_off());
00857 }
00858 }
00859
00860 _has_mouse = false;
00861 clear_current_regions();
00862
00863 } else {
00864
00865 const EventStoreVec2 *xy;
00866 DCAST_INTO_V(xy, input.get_data(_xy_input).get_ptr());
00867 const LVecBase2f &p = xy->get_value();
00868 _mouse.set(p[0], p[1]);
00869
00870 if (!_geometry.is_null()) {
00871
00872 _geometry->set_transform(TransformState::make_pos(LVecBase3f(p[0], 0, p[1])));
00873 if (!_has_mouse) {
00874
00875 _geometry->set_draw_mask(DrawMask::all_on());
00876 }
00877 }
00878
00879 _has_mouse = true;
00880
00881 VRegions regions;
00882 get_over_regions(regions, _mouse);
00883 set_current_regions(regions);
00884 }
00885
00886 _suppress_flags = 0;
00887 if (_preferred_region != (MouseWatcherRegion *)NULL) {
00888 _suppress_flags = _preferred_region->get_suppress_flags();
00889 }
00890
00891
00892 if (input.has_data(_button_events_input)) {
00893 const ButtonEventList *button_events;
00894 DCAST_INTO_V(button_events, input.get_data(_button_events_input).get_ptr());
00895 int num_events = button_events->get_num_events();
00896 for (int i = 0; i < num_events; i++) {
00897 const ButtonEvent &be = button_events->get_event(i);
00898 _mods.add_event(be);
00899
00900 switch (be._type) {
00901 case ButtonEvent::T_down:
00902 press(be._button);
00903 break;
00904
00905 case ButtonEvent::T_up:
00906 release(be._button);
00907 break;
00908
00909 case ButtonEvent::T_keystroke:
00910 keystroke(be._keycode);
00911 break;
00912
00913 case ButtonEvent::T_resume_down:
00914
00915 break;
00916 }
00917 }
00918 }
00919
00920 if (_has_mouse &&
00921 (_suppress_flags & MouseWatcherRegion::SF_mouse_position) == 0) {
00922
00923 output.set_data(_xy_output, input.get_data(_xy_input));
00924 output.set_data(_pixel_xy_output, input.get_data(_pixel_xy_input));
00925 }
00926
00927 int suppress_buttons = (_suppress_flags & MouseWatcherRegion::SF_any_button);
00928 if (suppress_buttons == MouseWatcherRegion::SF_any_button) {
00929
00930
00931 } else if (suppress_buttons != 0) {
00932
00933 _button_events->clear();
00934
00935 if (input.has_data(_button_events_input)) {
00936 const ButtonEventList *button_events;
00937 DCAST_INTO_V(button_events, input.get_data(_button_events_input).get_ptr());
00938 int num_events = button_events->get_num_events();
00939 for (int i = 0; i < num_events; i++) {
00940 const ButtonEvent &be = button_events->get_event(i);
00941 bool suppress = true;
00942
00943 if (be._type != ButtonEvent::T_keystroke &&
00944 MouseButton::is_mouse_button(be._button)) {
00945 suppress = ((suppress_buttons & MouseWatcherRegion::SF_mouse_button) != 0);
00946 } else {
00947 suppress = ((suppress_buttons & MouseWatcherRegion::SF_other_button) != 0);
00948 }
00949
00950 if (!suppress) {
00951
00952 _button_events->add_event(be);
00953 }
00954 }
00955 }
00956
00957 if (_button_events->get_num_events() != 0) {
00958 output.set_data(_button_events_output, EventParameter(_button_events));
00959 }
00960
00961 } else {
00962
00963 output.set_data(_button_events_output, input.get_data(_button_events_input));
00964 }
00965 }
00966