Panda3D
 All Classes Functions Variables Enumerations
rocketInputHandler.cxx
00001 // Filename: rocketInputHandler.cxx
00002 // Created by:  rdb (20Dec11)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "rocketInputHandler.h"
00016 #include "buttonEventList.h"
00017 #include "dataGraphTraverser.h"
00018 #include "linmath_events.h"
00019 #include "rocketRenderInterface.h"
00020 #include "keyboardButton.h"
00021 #include "mouseButton.h"
00022 
00023 #include <Rocket/Core/Input.h>
00024 
00025 using namespace Rocket::Core::Input;
00026 
00027 TypeHandle RocketInputHandler::_type_handle;
00028 
00029 ////////////////////////////////////////////////////////////////////
00030 //     Function: RocketInputHandler::Constructor
00031 //       Access: Published
00032 //  Description:
00033 ////////////////////////////////////////////////////////////////////
00034 RocketInputHandler::
00035 RocketInputHandler(const string &name) :
00036   DataNode(name),
00037   _modifiers(0),
00038   _wheel_delta(0)
00039 {
00040   _pixel_xy_input = define_input("pixel_xy", EventStoreVec2::get_class_type());
00041   _button_events_input = define_input("button_events", ButtonEventList::get_class_type());
00042 }
00043 
00044 ////////////////////////////////////////////////////////////////////
00045 //     Function: RocketInputHandler::Destructor
00046 //       Access: Published
00047 //  Description:
00048 ////////////////////////////////////////////////////////////////////
00049 RocketInputHandler::
00050 ~RocketInputHandler() {
00051 }
00052 
00053 ////////////////////////////////////////////////////////////////////
00054 //     Function: RocketInputHandler::get_rocket_key
00055 //       Access: Published
00056 //  Description: Returns the libRocket KeyIdentifier for the given
00057 //               ButtonHandle, or KI_UNKNOWN (0) if it wasn't known.
00058 ////////////////////////////////////////////////////////////////////
00059 int RocketInputHandler::
00060 get_rocket_key(const ButtonHandle handle) {
00061   static pmap<int, int> keymap;
00062   pmap<int, int>::const_iterator it;
00063 
00064   if (keymap.size() > 0) {
00065     it = keymap.find(handle.get_index());
00066 
00067     if (it == keymap.end()) {
00068       return 0;
00069     } else {
00070       return it->second;
00071     }
00072   }
00073 
00074   keymap[KeyboardButton::space().get_index()]        = KI_SPACE;
00075   keymap[KeyboardButton::backspace().get_index()]    = KI_BACK;
00076   keymap[KeyboardButton::tab().get_index()]          = KI_TAB;
00077   keymap[KeyboardButton::enter().get_index()]        = KI_RETURN;
00078   keymap[KeyboardButton::escape().get_index()]       = KI_ESCAPE;
00079   keymap[KeyboardButton::end().get_index()]          = KI_END;
00080   keymap[KeyboardButton::home().get_index()]         = KI_HOME;
00081   keymap[KeyboardButton::left().get_index()]         = KI_LEFT;
00082   keymap[KeyboardButton::up().get_index()]           = KI_UP;
00083   keymap[KeyboardButton::right().get_index()]        = KI_RIGHT;
00084   keymap[KeyboardButton::down().get_index()]         = KI_DOWN;
00085   keymap[KeyboardButton::insert().get_index()]       = KI_INSERT;
00086   keymap[KeyboardButton::del().get_index()]          = KI_DELETE;
00087   keymap[KeyboardButton::caps_lock().get_index()]    = KI_CAPITAL;
00088   keymap[KeyboardButton::f1().get_index()]           = KI_F1;
00089   keymap[KeyboardButton::f10().get_index()]          = KI_F10;
00090   keymap[KeyboardButton::f11().get_index()]          = KI_F11;
00091   keymap[KeyboardButton::f12().get_index()]          = KI_F12;
00092   keymap[KeyboardButton::f13().get_index()]          = KI_F13;
00093   keymap[KeyboardButton::f14().get_index()]          = KI_F14;
00094   keymap[KeyboardButton::f15().get_index()]          = KI_F15;
00095   keymap[KeyboardButton::f16().get_index()]          = KI_F16;
00096   keymap[KeyboardButton::f2().get_index()]           = KI_F2;
00097   keymap[KeyboardButton::f3().get_index()]           = KI_F3;
00098   keymap[KeyboardButton::f4().get_index()]           = KI_F4;
00099   keymap[KeyboardButton::f5().get_index()]           = KI_F5;
00100   keymap[KeyboardButton::f6().get_index()]           = KI_F6;
00101   keymap[KeyboardButton::f7().get_index()]           = KI_F7;
00102   keymap[KeyboardButton::f8().get_index()]           = KI_F8;
00103   keymap[KeyboardButton::f9().get_index()]           = KI_F9;
00104   keymap[KeyboardButton::help().get_index()]         = KI_HELP;
00105   keymap[KeyboardButton::lcontrol().get_index()]     = KI_LCONTROL;
00106   keymap[KeyboardButton::lshift().get_index()]       = KI_LSHIFT;
00107   keymap[KeyboardButton::num_lock().get_index()]     = KI_NUMLOCK;
00108   keymap[KeyboardButton::page_down().get_index()]    = KI_NEXT;
00109   keymap[KeyboardButton::page_up().get_index()]      = KI_PRIOR;
00110   keymap[KeyboardButton::pause().get_index()]        = KI_PAUSE;
00111   keymap[KeyboardButton::print_screen().get_index()] = KI_SNAPSHOT;
00112   keymap[KeyboardButton::rcontrol().get_index()]     = KI_RCONTROL;
00113   keymap[KeyboardButton::rshift().get_index()]       = KI_RSHIFT;
00114   keymap[KeyboardButton::scroll_lock().get_index()]  = KI_SCROLL;
00115 
00116   for (char c = 'a'; c <= 'z'; ++c) {
00117     keymap[KeyboardButton::ascii_key(c).get_index()] = (c - 'a') + KI_A;
00118   }
00119   for (char c = '0'; c <= '9'; ++c) {
00120     keymap[KeyboardButton::ascii_key(c).get_index()] = (c - '0') + KI_0;
00121   }
00122 
00123   it = keymap.find(handle.get_index());
00124   if (it != keymap.end()) {
00125     return it->second;
00126   }
00127   return 0;
00128 }
00129 
00130 ////////////////////////////////////////////////////////////////////
00131 //     Function: RocketInputHandler::do_transmit_data
00132 //       Access: Protected, Virtual
00133 //  Description: The virtual implementation of transmit_data().  This
00134 //               function receives an array of input parameters and
00135 //               should generate an array of output parameters.  The
00136 //               input parameters may be accessed with the index
00137 //               numbers returned by the define_input() calls that
00138 //               were made earlier (presumably in the constructor);
00139 //               likewise, the output parameters should be set with
00140 //               the index numbers returned by the define_output()
00141 //               calls.
00142 ////////////////////////////////////////////////////////////////////
00143 void RocketInputHandler::
00144 do_transmit_data(DataGraphTraverser *trav, const DataNodeTransmit &input,
00145                  DataNodeTransmit &output) {
00146   Thread *current_thread = trav->get_current_thread();
00147   MutexHolder holder(_lock);
00148 
00149   if (input.has_data(_pixel_xy_input)) {
00150     // The mouse is within the window.  Get the current mouse position.
00151     const EventStoreVec2 *pixel_xy;
00152     DCAST_INTO_V(pixel_xy, input.get_data(_pixel_xy_input).get_ptr());
00153     LVecBase2 p = pixel_xy->get_value();
00154 
00155     // Determine if mouse moved from last position
00156     if (p != _mouse_xy) {
00157       _mouse_xy_changed = true;
00158       _mouse_xy = p;
00159     }
00160   }
00161 
00162   ButtonEventList new_button_events;
00163 
00164   // Look for new button events.
00165   if (input.has_data(_button_events_input)) {
00166     const ButtonEventList *this_button_events;
00167     DCAST_INTO_V(this_button_events, input.get_data(_button_events_input).get_ptr());
00168     int num_events = this_button_events->get_num_events();
00169     for (int i = 0; i < num_events; i++) {
00170       const ButtonEvent &be = this_button_events->get_event(i);
00171 
00172       int rocket_key = KI_UNKNOWN;
00173 
00174       switch (be._type) {
00175       case ButtonEvent::T_down:
00176         if (be._button == KeyboardButton::control()) {
00177           _modifiers |= KM_CTRL;
00178         } else if (be._button == KeyboardButton::shift()) {
00179           _modifiers |= KM_SHIFT;
00180         } else if (be._button == KeyboardButton::alt()) {
00181           _modifiers |= KM_ALT;
00182         } else if (be._button == KeyboardButton::meta()) {
00183           _modifiers |= KM_META;
00184 
00185         } else if (be._button == KeyboardButton::enter()) {
00186           _text_input.push_back('\n');
00187 
00188         } else if (be._button == MouseButton::wheel_up()) {
00189           _wheel_delta -= 1;
00190         } else if (be._button == MouseButton::wheel_down()) {
00191           _wheel_delta += 1;
00192 
00193         } else if (be._button == MouseButton::one()) {
00194           _mouse_buttons[0] = true;
00195         } else if (be._button == MouseButton::two()) {
00196           _mouse_buttons[1] = true;
00197         } else if (be._button == MouseButton::three()) {
00198           _mouse_buttons[2] = true;
00199         } else if (be._button == MouseButton::four()) {
00200           _mouse_buttons[3] = true;
00201         } else if (be._button == MouseButton::five()) {
00202           _mouse_buttons[4] = true;
00203         }
00204 
00205         rocket_key = get_rocket_key(be._button);
00206         if (rocket_key != KI_UNKNOWN) {
00207           _keys[rocket_key] = true;
00208         }
00209         break;
00210 
00211       case ButtonEvent::T_repeat:
00212         if (be._button == KeyboardButton::enter()) {
00213           _text_input.push_back('\n');
00214         }
00215 
00216         rocket_key = get_rocket_key(be._button);
00217         if (rocket_key != KI_UNKNOWN) {
00218           _repeated_keys.push_back(rocket_key);
00219         }
00220         break;
00221 
00222       case ButtonEvent::T_up:
00223         if (be._button == KeyboardButton::control()) {
00224           _modifiers &= ~KM_CTRL;
00225         } else if (be._button == KeyboardButton::shift()) {
00226           _modifiers &= ~KM_SHIFT;
00227         } else if (be._button == KeyboardButton::alt()) {
00228           _modifiers &= ~KM_ALT;
00229         } else if (be._button == KeyboardButton::meta()) {
00230           _modifiers &= ~KM_META;
00231 
00232         } else if (be._button == MouseButton::one()) {
00233           _mouse_buttons[0] = false;
00234         } else if (be._button == MouseButton::two()) {
00235           _mouse_buttons[1] = false;
00236         } else if (be._button == MouseButton::three()) {
00237           _mouse_buttons[2] = false;
00238         } else if (be._button == MouseButton::four()) {
00239           _mouse_buttons[3] = false;
00240         } else if (be._button == MouseButton::five()) {
00241           _mouse_buttons[4] = false;
00242         }
00243 
00244         rocket_key = get_rocket_key(be._button);
00245         if (rocket_key != KI_UNKNOWN) {
00246           _keys[rocket_key] = false;
00247         }
00248         break;
00249 
00250       case ButtonEvent::T_keystroke:
00251         // Ignore control characters; otherwise, they actually get added to strings in the UI.
00252         if (be._keycode > 0x1F && (be._keycode < 0x7F || be._keycode > 0x9F)) {
00253           _text_input.push_back(be._keycode);
00254         }
00255         break;
00256 
00257       case ButtonEvent::T_resume_down:
00258         break;
00259 
00260       case ButtonEvent::T_move:
00261         break;
00262       }
00263     }
00264   }
00265 }
00266 
00267 ////////////////////////////////////////////////////////////////////
00268 //     Function: RocketInputHandler::update_context
00269 //       Access: Public
00270 //  Description: Updates the libRocket context with the changes
00271 //               that we have gathered in do_transmit_data.
00272 //               Also calls Update() on the context.
00273 ////////////////////////////////////////////////////////////////////
00274 void RocketInputHandler::
00275 update_context(Rocket::Core::Context *context, int xoffs, int yoffs) {
00276   MutexHolder holder(_lock);
00277 
00278   if (_mouse_xy_changed) {
00279     _mouse_xy_changed = false;
00280 
00281     context->ProcessMouseMove(_mouse_xy.get_x() - xoffs,
00282                               _mouse_xy.get_y() - yoffs, _modifiers);
00283   }
00284 
00285   if (_mouse_buttons.size() > 0) {
00286     ButtonActivityMap::const_iterator it;
00287     for (it = _mouse_buttons.begin(); it != _mouse_buttons.end(); ++it) {
00288       if (it->second) {
00289         context->ProcessMouseButtonDown(it->first, _modifiers);
00290       } else {
00291         context->ProcessMouseButtonUp(it->first, _modifiers);
00292       }
00293     }
00294     _mouse_buttons.clear();
00295   }
00296 
00297   if (_wheel_delta != 0) {
00298     context->ProcessMouseWheel(_wheel_delta, _modifiers);
00299     _wheel_delta = 0;
00300   }
00301 
00302   if (_keys.size() > 0) {
00303     ButtonActivityMap::const_iterator it;
00304     for (it = _keys.begin(); it != _keys.end(); ++it) {
00305       if (it->second) {
00306         context->ProcessKeyDown((KeyIdentifier) it->first, _modifiers);
00307       } else {
00308         context->ProcessKeyUp((KeyIdentifier) it->first, _modifiers);
00309       }
00310     }
00311     _keys.clear();
00312   }
00313 
00314   if (_repeated_keys.size() > 0) {
00315     pvector<int>::const_iterator it;
00316 
00317     for (it = _repeated_keys.begin(); it != _repeated_keys.end(); ++it) {
00318       context->ProcessKeyUp((KeyIdentifier) *it, _modifiers);
00319       context->ProcessKeyDown((KeyIdentifier) *it, _modifiers);
00320     }
00321     _repeated_keys.clear();
00322   }
00323 
00324   if (_text_input.size() > 0) {
00325     pvector<short>::const_iterator it;
00326     for (it = _text_input.begin(); it != _text_input.end(); ++it) {
00327       context->ProcessTextInput(*it);
00328     }
00329     _text_input.clear();
00330   }
00331 
00332   context->Update();
00333 }
 All Classes Functions Variables Enumerations