00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #include "buttonThrower.h"
00016
00017 #include "buttonEvent.h"
00018 #include "buttonEventList.h"
00019 #include "dataNodeTransmit.h"
00020 #include "throw_event.h"
00021 #include "event.h"
00022 #include "indent.h"
00023 #include "dcast.h"
00024
00025 TypeHandle ButtonThrower::_type_handle;
00026
00027
00028
00029
00030
00031
00032
00033 ButtonThrower::
00034 ButtonThrower(const string &name) :
00035 DataNode(name)
00036 {
00037 _button_events_input = define_input("button_events", ButtonEventList::get_class_type());
00038 _button_events_output = define_output("button_events", ButtonEventList::get_class_type());
00039
00040 _button_events = new ButtonEventList;
00041
00042 _specific_flag = true;
00043 _time_flag = false;
00044 _throw_buttons_active = false;
00045 }
00046
00047
00048
00049
00050
00051
00052 ButtonThrower::
00053 ~ButtonThrower() {
00054 }
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064 void ButtonThrower::
00065 add_parameter(const EventParameter &obj) {
00066 _parameters.push_back(obj);
00067 }
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077 int ButtonThrower::
00078 get_num_parameters() const {
00079 return _parameters.size();
00080 }
00081
00082
00083
00084
00085
00086
00087
00088
00089 EventParameter ButtonThrower::
00090 get_parameter(int n) const {
00091 nassertr(n >= 0 && n < (int)_parameters.size(), EventParameter(0));
00092 return _parameters[n];
00093 }
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114 bool ButtonThrower::
00115 add_throw_button(const ModifierButtons &mods, const ButtonHandle &button) {
00116 ThrowButtonDef &def = _throw_buttons[button];
00117
00118
00119
00120
00121 ThrowButtonDef::iterator di;
00122 for (di = def.begin(); di != def.end(); ++di) {
00123 if (mods.matches(*di)) {
00124 return false;
00125 }
00126 }
00127
00128 def.push_back(mods);
00129 return true;
00130 }
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142 bool ButtonThrower::
00143 remove_throw_button(const ModifierButtons &mods, const ButtonHandle &button) {
00144 ThrowButtons::iterator ti = _throw_buttons.find(button);
00145 if (ti == _throw_buttons.end()) {
00146
00147 return false;
00148 }
00149
00150 ThrowButtonDef &def = (*ti).second;
00151
00152
00153
00154 ThrowButtonDef::iterator di;
00155 for (di = def.begin(); di != def.end(); ++di) {
00156 if (mods.matches(*di)) {
00157 def.erase(di);
00158 if (def.empty()) {
00159 _throw_buttons.erase(ti);
00160 }
00161 return true;
00162 }
00163 }
00164
00165
00166
00167 return false;
00168 }
00169
00170
00171
00172
00173
00174
00175
00176
00177 bool ButtonThrower::
00178 has_throw_button(const ModifierButtons &mods, const ButtonHandle &button) const {
00179 ThrowButtons::const_iterator ti = _throw_buttons.find(button);
00180 if (ti == _throw_buttons.end()) {
00181
00182 return false;
00183 }
00184
00185 const ThrowButtonDef &def = (*ti).second;
00186
00187
00188
00189 ThrowButtonDef::const_iterator di;
00190 for (di = def.begin(); di != def.end(); ++di) {
00191 if (mods.matches(*di)) {
00192 return true;
00193 }
00194 }
00195
00196
00197
00198 return false;
00199 }
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212 bool ButtonThrower::
00213 has_throw_button(const ButtonHandle &button) const {
00214 ThrowButtons::const_iterator ti = _throw_buttons.find(button);
00215 if (ti == _throw_buttons.end()) {
00216
00217 return false;
00218 }
00219
00220 const ThrowButtonDef &def = (*ti).second;
00221 return !def.empty();
00222 }
00223
00224
00225
00226
00227
00228
00229
00230 void ButtonThrower::
00231 clear_throw_buttons() {
00232 _throw_buttons.clear();
00233 }
00234
00235
00236
00237
00238
00239
00240
00241 void ButtonThrower::
00242 write(ostream &out, int indent_level) const {
00243 DataNode::write(out, indent_level);
00244 if (_throw_buttons_active) {
00245 indent(out, indent_level)
00246 << "Processing keys:\n";
00247
00248 ThrowButtons::const_iterator ti;
00249 for (ti = _throw_buttons.begin(); ti != _throw_buttons.end(); ++ti) {
00250 ButtonHandle button = (*ti).first;
00251 const ThrowButtonDef &def = (*ti).second;
00252 ThrowButtonDef::const_iterator di;
00253 for (di = def.begin(); di != def.end(); ++di) {
00254 indent(out, indent_level + 2)
00255 << (*di).get_prefix() << button.get_name() << "\n";
00256 }
00257 }
00258 }
00259 }
00260
00261
00262
00263
00264
00265
00266
00267 void ButtonThrower::
00268 do_specific_event(const string &event_name, double time) {
00269 if (_specific_flag) {
00270 PT(Event) event = new Event(_prefix + event_name);
00271
00272 if (_time_flag) {
00273 event->add_parameter(time);
00274 }
00275
00276 ParameterList::const_iterator pi;
00277 for (pi = _parameters.begin(); pi != _parameters.end(); ++pi) {
00278 event->add_parameter(*pi);
00279 }
00280
00281 throw_event(event);
00282 }
00283 }
00284
00285
00286
00287
00288
00289
00290
00291 void ButtonThrower::
00292 do_general_event(const ButtonEvent &button_event, const string &button_name) {
00293 string event_name;
00294 switch (button_event._type) {
00295 case ButtonEvent::T_down:
00296 event_name = _button_down_event;
00297 break;
00298
00299 case ButtonEvent::T_resume_down:
00300 break;
00301
00302 case ButtonEvent::T_up:
00303 event_name = _button_up_event;
00304 break;
00305
00306 case ButtonEvent::T_repeat:
00307 event_name = _button_repeat_event;
00308 break;
00309
00310 case ButtonEvent::T_keystroke:
00311 event_name = _keystroke_event;
00312 break;
00313
00314 case ButtonEvent::T_candidate:
00315 event_name = _candidate_event;
00316 break;
00317
00318 case ButtonEvent::T_move:
00319 event_name = _move_event;
00320 break;
00321 }
00322 if (event_name.empty()) {
00323
00324 return;
00325 }
00326
00327 PT(Event) event = new Event(event_name);
00328
00329 if (_time_flag) {
00330 event->add_parameter(button_event._time);
00331 }
00332
00333
00334 switch (button_event._type) {
00335 case ButtonEvent::T_down:
00336 case ButtonEvent::T_resume_down:
00337 case ButtonEvent::T_up:
00338 case ButtonEvent::T_repeat:
00339 event->add_parameter(button_name);
00340 break;
00341
00342 case ButtonEvent::T_keystroke:
00343 event->add_parameter(wstring(1, button_event._keycode));
00344 break;
00345
00346 case ButtonEvent::T_candidate:
00347 event->add_parameter(button_event._candidate_string);
00348 break;
00349
00350 case ButtonEvent::T_move:
00351 event_name = _move_event;
00352 break;
00353 }
00354
00355 ParameterList::const_iterator pi;
00356 for (pi = _parameters.begin(); pi != _parameters.end(); ++pi) {
00357 event->add_parameter(*pi);
00358 }
00359
00360 throw_event(event);
00361 }
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376 void ButtonThrower::
00377 do_transmit_data(DataGraphTraverser *, const DataNodeTransmit &input,
00378 DataNodeTransmit &output) {
00379
00380
00381 _button_events->clear();
00382
00383 if (input.has_data(_button_events_input)) {
00384 const ButtonEventList *button_events;
00385 DCAST_INTO_V(button_events, input.get_data(_button_events_input).get_ptr());
00386
00387 int num_events = button_events->get_num_events();
00388 for (int i = 0; i < num_events; i++) {
00389 const ButtonEvent &be = button_events->get_event(i);
00390 string event_name = be._button.get_name();
00391
00392 if (be._type == ButtonEvent::T_down || be._type == ButtonEvent::T_repeat) {
00393
00394 if (!_mods.button_down(be._button)) {
00395
00396
00397 event_name = _mods.get_prefix() + event_name;
00398 }
00399
00400 if (!_throw_buttons_active || has_throw_button(_mods, be._button)) {
00401
00402 if (be._type == ButtonEvent::T_repeat) {
00403 do_specific_event(event_name + "-repeat", be._time);
00404 } else {
00405 do_specific_event(event_name, be._time);
00406 }
00407 do_general_event(be, event_name);
00408
00409 } else {
00410
00411
00412 _button_events->add_event(be);
00413 }
00414
00415 } else if (be._type == ButtonEvent::T_resume_down) {
00416
00417
00418
00419
00420 _mods.button_down(be._button);
00421
00422 } else if (be._type == ButtonEvent::T_up) {
00423
00424 _mods.button_up(be._button);
00425
00426
00427
00428
00429 if (!_throw_buttons_active || has_throw_button(be._button)) {
00430 do_specific_event(event_name + "-up", be._time);
00431 do_general_event(be, event_name);
00432 }
00433 if (_throw_buttons_active) {
00434
00435
00436
00437
00438 _button_events->add_event(be);
00439 }
00440
00441 } else {
00442
00443
00444 _button_events->add_event(be);
00445 do_general_event(be, "");
00446 }
00447 }
00448 }
00449
00450 output.set_data(_button_events_output, EventParameter(_button_events));
00451 }