Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/tform/buttonThrower.cxx

Go to the documentation of this file.
00001 // Filename: buttonThrower.cxx
00002 // Created by:  drose (12Mar02)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #include "buttonThrower.h"
00020 
00021 #include "buttonEvent.h"
00022 #include "buttonEventList.h"
00023 #include "dataNodeTransmit.h"
00024 #include "throw_event.h"
00025 #include "event.h"
00026 #include "indent.h"
00027 #include "dcast.h"
00028 
00029 TypeHandle ButtonThrower::_type_handle;
00030 
00031 
00032 ////////////////////////////////////////////////////////////////////
00033 //     Function: ButtonThrower::Constructor
00034 //       Access: Public
00035 //  Description:
00036 ////////////////////////////////////////////////////////////////////
00037 ButtonThrower::
00038 ButtonThrower(const string &name) :
00039   DataNode(name)
00040 {
00041   _button_events_input = define_input("button_events", ButtonEventList::get_class_type());
00042   _button_events_output = define_output("button_events", ButtonEventList::get_class_type());
00043 
00044   _button_events = new ButtonEventList;
00045 
00046   _throw_buttons_active = false;
00047 }
00048 
00049 ////////////////////////////////////////////////////////////////////
00050 //     Function: ButtonThrower::Destructor
00051 //       Access: Published, Virtual
00052 //  Description:
00053 ////////////////////////////////////////////////////////////////////
00054 ButtonThrower::
00055 ~ButtonThrower() {
00056 }
00057 
00058 
00059 ////////////////////////////////////////////////////////////////////
00060 //     Function: ButtonThrower::set_prefix
00061 //       Access: Published
00062 //  Description: Sets the prefix which is prepended to all event names
00063 //               thrown by this object.
00064 ////////////////////////////////////////////////////////////////////
00065 void ButtonThrower::
00066 set_prefix(const string &prefix) {
00067   _prefix = prefix;
00068 }
00069 
00070 
00071 ////////////////////////////////////////////////////////////////////
00072 //     Function: ButtonThrower::has_prefix
00073 //       Access: Published
00074 //  Description: Returns true if the ButtonThrower has a prefix set,
00075 //               false otherwise.
00076 ////////////////////////////////////////////////////////////////////
00077 bool ButtonThrower::
00078 has_prefix() const {
00079   return !_prefix.empty();
00080 }
00081 
00082 ////////////////////////////////////////////////////////////////////
00083 //     Function: ButtonThrower::get_prefix
00084 //       Access: Published
00085 //  Description: Returns the prefix that has been set on this
00086 //               ButtonThrower.  See set_prefix().
00087 ////////////////////////////////////////////////////////////////////
00088 string ButtonThrower::
00089 get_prefix() const {
00090   return _prefix;
00091 }
00092 
00093 ////////////////////////////////////////////////////////////////////
00094 //     Function: ButtonThrower::add_parameter
00095 //       Access: Public
00096 //  Description: Adds the indicated parameter to the list of
00097 //               parameters that will be passed with each event
00098 //               generated by this ButtonThrower.
00099 ////////////////////////////////////////////////////////////////////
00100 void ButtonThrower::
00101 add_parameter(const EventParameter &obj) {
00102   _parameters.push_back(obj);
00103 }
00104 
00105 
00106 ////////////////////////////////////////////////////////////////////
00107 //     Function: ButtonThrower::get_num_parameters
00108 //       Access: Public
00109 //  Description: Returns the number of parameters that have been added
00110 //               to the list of parameters to be passed with each
00111 //               event generated by this ButtonThrower.
00112 ////////////////////////////////////////////////////////////////////
00113 int ButtonThrower::
00114 get_num_parameters() const {
00115   return _parameters.size();
00116 }
00117 
00118 ////////////////////////////////////////////////////////////////////
00119 //     Function: ButtonThrower::get_parameter
00120 //       Access: Public
00121 //  Description: Returns the nth parameter that has been added to the
00122 //               list of parameters passed with each event generated
00123 //               by this ButtonThrower.
00124 ////////////////////////////////////////////////////////////////////
00125 EventParameter ButtonThrower::
00126 get_parameter(int n) const {
00127   nassertr(n >= 0 && n < (int)_parameters.size(), EventParameter(0));
00128   return _parameters[n];
00129 }
00130 
00131 ////////////////////////////////////////////////////////////////////
00132 //     Function: ButtonThrower::get_modifier_buttons
00133 //       Access: Published
00134 //  Description: Returns the set of ModifierButtons that the
00135 //               ButtonThrower will consider important enough to
00136 //               prepend the event name with.  Normally, this set will
00137 //               be empty, and the ButtonThrower will therefore ignore
00138 //               all ModifierButtons attached to the key events, but
00139 //               if one or more buttons have been added to this set,
00140 //               and those modifier buttons are set on the button
00141 //               event, then the event name will be prepended with the
00142 //               names of the modifier buttons.
00143 ////////////////////////////////////////////////////////////////////
00144 const ModifierButtons &ButtonThrower::
00145 get_modifier_buttons() const {
00146   return _mods;
00147 }
00148 
00149 ////////////////////////////////////////////////////////////////////
00150 //     Function: ButtonThrower::set_modifier_buttons
00151 //       Access: Published
00152 //  Description: Changes the set of ModifierButtons that the
00153 //               ButtonThrower will consider important enough to
00154 //               prepend the event name with.  Normally, this set will
00155 //               be empty, and the ButtonThrower will therefore ignore
00156 //               all ModifierButtons attached to the key events, but
00157 //               if one or more buttons have been added to this set,
00158 //               then the event name will be prepended with the names
00159 //               of the modifier buttons.
00160 //
00161 //               It is recommended that you change this setting by
00162 //               first calling get_modifier_buttons(), making
00163 //               adjustments, and passing the new value to
00164 //               set_modifier_buttons().  This way the current state
00165 //               of the modifier buttons will not be lost.
00166 ////////////////////////////////////////////////////////////////////
00167 void ButtonThrower::
00168 set_modifier_buttons(const ModifierButtons &mods) {
00169   _mods = mods;
00170 }
00171 
00172 ////////////////////////////////////////////////////////////////////
00173 //     Function: ButtonThrower::set_throw_buttons_active
00174 //       Access: Published
00175 //  Description: Sets the flag that indicates whether the
00176 //               ButtonThrower will only process events for the
00177 //               explicitly named buttons or not.  Normally this is
00178 //               false, meaning all buttons are processed; set it true
00179 //               to indicate that only some buttons should be
00180 //               processed.  See add_throw_button().
00181 ////////////////////////////////////////////////////////////////////
00182 void ButtonThrower::
00183 set_throw_buttons_active(bool flag) {
00184   _throw_buttons_active = flag;
00185 }
00186 
00187 ////////////////////////////////////////////////////////////////////
00188 //     Function: ButtonThrower::get_throw_buttons_active
00189 //       Access: Published
00190 //  Description: Returns the flag that indicates whether the
00191 //               ButtonThrower will only process events for the
00192 //               explicitly named buttons or not.  See
00193 //               set_throw_buttons_active().
00194 ////////////////////////////////////////////////////////////////////
00195 bool ButtonThrower::
00196 get_throw_buttons_active() const {
00197   return _throw_buttons_active;
00198 }
00199 
00200 ////////////////////////////////////////////////////////////////////
00201 //     Function: ButtonThrower::add_throw_button
00202 //       Access: Published
00203 //  Description: Adds a new button to the set of buttons that the
00204 //               ButtonThrower explicitly processes.
00205 //
00206 //               If set_throw_buttons_active is false (which is the
00207 //               default), the ButtonThrower will process all buttons.
00208 //               Otherwise, the ButtonThrower will only process events
00209 //               for the button(s) explicitly named by this function;
00210 //               buttons not on the list will be ignored by this
00211 //               object and passed on downstream to the child node(s)
00212 //               in the data graph.  A button that *is* on the list
00213 //               will be processed by the ButtonThrower and not passed
00214 //               on to the child node(s).
00215 //
00216 //               The return value is true if the button is added, or
00217 //               false if it was already in the set.
00218 ////////////////////////////////////////////////////////////////////
00219 bool ButtonThrower::
00220 add_throw_button(const ModifierButtons &mods, const ButtonHandle &button) {
00221   ThrowButtonDef &def = _throw_buttons[button];
00222 
00223   // This is a vector of ModifierButtons for which the indicated
00224   // button is handled.  Make sure the current ModifierButtons object
00225   // is not already on the list.
00226   ThrowButtonDef::iterator di;
00227   for (di = def.begin(); di != def.end(); ++di) {
00228     if (mods.matches(*di)) {
00229       return false;
00230     }
00231   }
00232 
00233   def.push_back(mods);
00234   return true;
00235 }
00236 
00237 ////////////////////////////////////////////////////////////////////
00238 //     Function: ButtonThrower::remove_throw_button
00239 //       Access: Published
00240 //  Description: Removes the indicated button from the set of buttons
00241 //               that the ButtonThrower explicitly processes.  See
00242 //               add_throw_button().
00243 //
00244 //               The return value is true if the button is removed, or
00245 //               false if it was not on the set.
00246 ////////////////////////////////////////////////////////////////////
00247 bool ButtonThrower::
00248 remove_throw_button(const ModifierButtons &mods, const ButtonHandle &button) {
00249   ThrowButtons::iterator ti = _throw_buttons.find(button);
00250   if (ti == _throw_buttons.end()) {
00251     // No buttons of this kind are in the set.
00252     return false;
00253   }
00254 
00255   ThrowButtonDef &def = (*ti).second;
00256 
00257   // This is a vector of ModifierButtons for which the indicated
00258   // button is handled.
00259   ThrowButtonDef::iterator di;
00260   for (di = def.begin(); di != def.end(); ++di) {
00261     if (mods.matches(*di)) {
00262       def.erase(di);
00263       if (def.empty()) {
00264         _throw_buttons.erase(ti);
00265       }
00266       return true;
00267     }
00268   }
00269 
00270   // The indicated ModifierButtons are not applied to this button in
00271   // the set.
00272   return false;
00273 }
00274 
00275 ////////////////////////////////////////////////////////////////////
00276 //     Function: ButtonThrower::has_throw_button
00277 //       Access: Published
00278 //  Description: Returns true if the indicated button is on the set of
00279 //               buttons that will be processed by the ButtonThrower,
00280 //               false otherwise.  See add_throw_button().
00281 ////////////////////////////////////////////////////////////////////
00282 bool ButtonThrower::
00283 has_throw_button(const ModifierButtons &mods, const ButtonHandle &button) const {
00284   ThrowButtons::const_iterator ti = _throw_buttons.find(button);
00285   if (ti == _throw_buttons.end()) {
00286     // No buttons of this kind are in the set.
00287     return false;
00288   }
00289 
00290   const ThrowButtonDef &def = (*ti).second;
00291 
00292   // This is a vector of ModifierButtons for which the indicated
00293   // button is handled.
00294   ThrowButtonDef::const_iterator di;
00295   for (di = def.begin(); di != def.end(); ++di) {
00296     if (mods.matches(*di)) {
00297       return true;
00298     }
00299   }
00300 
00301   // The indicated ModifierButtons are not applied to this button in
00302   // the set.
00303   return false;
00304 }
00305 
00306 ////////////////////////////////////////////////////////////////////
00307 //     Function: ButtonThrower::has_throw_button
00308 //       Access: Published
00309 //  Description: Returns true if the indicated button, in conjunction
00310 //               with any nonspecified modifier buttons, is on the set
00311 //               of buttons that will be processed by the
00312 //               ButtonThrower.  That is to say, returns true if this
00313 //               button was ever passed as the second parameter
00314 //               add_throw_button(), regardless of what the first
00315 //               parameter was.
00316 ////////////////////////////////////////////////////////////////////
00317 bool ButtonThrower::
00318 has_throw_button(const ButtonHandle &button) const {
00319   ThrowButtons::const_iterator ti = _throw_buttons.find(button);
00320   if (ti == _throw_buttons.end()) {
00321     // No buttons of this kind are in the set.
00322     return false;
00323   }
00324 
00325   const ThrowButtonDef &def = (*ti).second;
00326   return !def.empty();
00327 }
00328 
00329 ////////////////////////////////////////////////////////////////////
00330 //     Function: ButtonThrower::clear_throw_buttons
00331 //       Access: Published
00332 //  Description: Empties the set of buttons that were added via
00333 //               add_throw_button().  See add_throw_button().
00334 ////////////////////////////////////////////////////////////////////
00335 void ButtonThrower::
00336 clear_throw_buttons() {
00337   _throw_buttons.clear();
00338 }
00339 
00340 ////////////////////////////////////////////////////////////////////
00341 //     Function: ButtonThrower::write
00342 //       Access: Public, Virtual
00343 //  Description: Throw all events for button events found in the data
00344 //               element.
00345 ////////////////////////////////////////////////////////////////////
00346 void ButtonThrower::
00347 write(ostream &out, int indent_level) const {
00348   DataNode::write(out, indent_level);
00349   if (_throw_buttons_active) {
00350     indent(out, indent_level)
00351       << "Processing keys:\n";
00352     // Write the list of buttons that we're processing too.
00353     ThrowButtons::const_iterator ti;
00354     for (ti = _throw_buttons.begin(); ti != _throw_buttons.end(); ++ti) {
00355       ButtonHandle button = (*ti).first;
00356       const ThrowButtonDef &def = (*ti).second;
00357       ThrowButtonDef::const_iterator di;
00358       for (di = def.begin(); di != def.end(); ++di) {
00359         indent(out, indent_level + 2)
00360           << (*di).get_prefix() << button.get_name() << "\n";
00361       }
00362     }
00363   }    
00364 }
00365 
00366 ////////////////////////////////////////////////////////////////////
00367 //     Function: ButtonThrower::do_throw_event
00368 //       Access: Private
00369 //  Description: Generates an event of the indicated name, adding on
00370 //               all of the user-requested parameters.
00371 ////////////////////////////////////////////////////////////////////
00372 void ButtonThrower::
00373 do_throw_event(const string &event_name) {
00374   Event *event = new Event(_prefix + event_name);
00375 
00376   ParameterList::const_iterator pi;
00377   for (pi = _parameters.begin(); pi != _parameters.end(); ++pi) {
00378     event->add_parameter(*pi);
00379   }
00380 
00381   throw_event(event);
00382 }
00383 
00384 ////////////////////////////////////////////////////////////////////
00385 //     Function: ButtonThrower::do_transmit_data
00386 //       Access: Protected, Virtual
00387 //  Description: The virtual implementation of transmit_data().  This
00388 //               function receives an array of input parameters and
00389 //               should generate an array of output parameters.  The
00390 //               input parameters may be accessed with the index
00391 //               numbers returned by the define_input() calls that
00392 //               were made earlier (presumably in the constructor);
00393 //               likewise, the output parameters should be set with
00394 //               the index numbers returned by the define_output()
00395 //               calls.
00396 ////////////////////////////////////////////////////////////////////
00397 void ButtonThrower::
00398 do_transmit_data(const DataNodeTransmit &input, DataNodeTransmit &output) {
00399   // Clear our outgoing button events.  We'll fill it up again with
00400   // just those events that want to carry on.
00401   _button_events->clear();
00402 
00403   if (input.has_data(_button_events_input)) {
00404     const ButtonEventList *button_events;
00405     DCAST_INTO_V(button_events, input.get_data(_button_events_input).get_ptr());
00406 
00407     int num_events = button_events->get_num_events();
00408     for (int i = 0; i < num_events; i++) {
00409       const ButtonEvent &be = button_events->get_event(i);
00410       string event_name = be._button.get_name();
00411 
00412       if (be._type == ButtonEvent::T_down) {
00413         // Button down.
00414         if (!_mods.button_down(be._button)) {
00415           // We only prepend modifier names on the button-down events,
00416           // and only for buttons which are not themselves modifiers.
00417           event_name = _mods.get_prefix() + event_name;
00418         }
00419 
00420         if (!_throw_buttons_active || has_throw_button(_mods, be._button)) {
00421           // Process this button.
00422           do_throw_event(event_name);
00423           
00424         } else {
00425           // Don't process this button; instead, pass it down to future
00426           // generations.
00427           _button_events->add_event(be);
00428         }
00429 
00430       } else if (be._type == ButtonEvent::T_resume_down) {
00431         // Button resume down.  The button was pressed at some earlier
00432         // time, and the event was only just now detected.  Don't
00433         // throw an event now (since we already missed it), but do
00434         // make sure our modifiers are up-to-date.
00435         _mods.button_down(be._button);
00436           
00437       } else if (be._type == ButtonEvent::T_up) {
00438         // Button up.
00439         _mods.button_up(be._button);
00440 
00441         // We always throw button "up" events if we have any
00442         // definition for the button at all, regardless of the state
00443         // of the modifier keys.
00444         if (!_throw_buttons_active || has_throw_button(be._button)) {
00445           do_throw_event(event_name + "-up");
00446         }
00447         if (_throw_buttons_active) {
00448           // Now pass the event on to future generations.  We always
00449           // pass "up" events, even if we are intercepting this
00450           // particular button; unless we're processing all buttons in
00451           // which case it doesn't matter.
00452           _button_events->add_event(be);
00453         }
00454 
00455       } else {
00456         // Some other kind of button event (e.g. keypress).  Don't
00457         // throw an event for this, but do pass it down.
00458         _button_events->add_event(be);
00459       }
00460     }
00461   }
00462 
00463   output.set_data(_button_events_output, EventParameter(_button_events));
00464 }

Generated on Fri May 2 00:44:23 2003 for Panda by doxygen1.3