Panda3D

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 == MouseButton::wheel_up()) {
00186           _wheel_delta -= 1;
00187         } else if (be._button == MouseButton::wheel_down()) {
00188           _wheel_delta += 1;
00189 
00190         } else if (be._button == MouseButton::one()) {
00191           _mouse_buttons[0] = true;
00192         } else if (be._button == MouseButton::two()) {
00193           _mouse_buttons[1] = true;
00194         } else if (be._button == MouseButton::three()) {
00195           _mouse_buttons[2] = true;
00196         } else if (be._button == MouseButton::four()) {
00197           _mouse_buttons[3] = true;
00198         } else if (be._button == MouseButton::five()) {
00199           _mouse_buttons[4] = true;
00200         }
00201 
00202         rocket_key = get_rocket_key(be._button);
00203         if (rocket_key != KI_UNKNOWN) {
00204           _keys[rocket_key] = true;
00205         }
00206         break;
00207 
00208       case ButtonEvent::T_repeat:
00209         rocket_key = get_rocket_key(be._button);
00210         if (rocket_key != KI_UNKNOWN) {
00211           _repeated_keys.push_back(rocket_key);
00212         }
00213         break;
00214 
00215       case ButtonEvent::T_up:
00216         if (be._button == KeyboardButton::control()) {
00217           _modifiers &= ~KM_CTRL;
00218         } else if (be._button == KeyboardButton::shift()) {
00219           _modifiers &= ~KM_SHIFT;
00220         } else if (be._button == KeyboardButton::alt()) {
00221           _modifiers &= ~KM_ALT;
00222         } else if (be._button == KeyboardButton::meta()) {
00223           _modifiers &= ~KM_META;
00224 
00225         } else if (be._button == MouseButton::one()) {
00226           _mouse_buttons[0] = false;
00227         } else if (be._button == MouseButton::two()) {
00228           _mouse_buttons[1] = false;
00229         } else if (be._button == MouseButton::three()) {
00230           _mouse_buttons[2] = false;
00231         } else if (be._button == MouseButton::four()) {
00232           _mouse_buttons[3] = false;
00233         } else if (be._button == MouseButton::five()) {
00234           _mouse_buttons[4] = false;
00235         }
00236 
00237         rocket_key = get_rocket_key(be._button);
00238         if (rocket_key != KI_UNKNOWN) {
00239           _keys[rocket_key] = false;
00240         }
00241         break;
00242 
00243       case ButtonEvent::T_keystroke:
00244         // Ignore control characters; otherwise, they actually get added to strings in the UI.
00245         if (be._keycode > 0x1F && (be._keycode < 0x7F || be._keycode > 0x9F)) {
00246           _text_input.push_back(be._keycode);
00247         }
00248         break;
00249 
00250       case ButtonEvent::T_resume_down:
00251         break;
00252 
00253       case ButtonEvent::T_move:
00254         break;
00255       }
00256     }
00257   }
00258 }
00259 
00260 ////////////////////////////////////////////////////////////////////
00261 //     Function: RocketInputHandler::update_context
00262 //       Access: Public
00263 //  Description: Updates the libRocket context with the changes
00264 //               that we have gathered in do_transmit_data.
00265 //               Also calls Update() on the context.
00266 ////////////////////////////////////////////////////////////////////
00267 void RocketInputHandler::
00268 update_context(Rocket::Core::Context *context, int xoffs, int yoffs) {
00269   MutexHolder holder(_lock);
00270 
00271   if (_mouse_xy_changed) {
00272     _mouse_xy_changed = false;
00273 
00274     context->ProcessMouseMove(_mouse_xy.get_x() - xoffs,
00275                               _mouse_xy.get_y() - yoffs, _modifiers);
00276   }
00277 
00278   if (_mouse_buttons.size() > 0) {
00279     ButtonActivityMap::const_iterator it;
00280     for (it = _mouse_buttons.begin(); it != _mouse_buttons.end(); ++it) {
00281       if (it->second) {
00282         context->ProcessMouseButtonDown(it->first, _modifiers);
00283       } else {
00284         context->ProcessMouseButtonUp(it->first, _modifiers);
00285       }
00286     }
00287     _mouse_buttons.clear();
00288   }
00289 
00290   if (_wheel_delta != 0) {
00291     context->ProcessMouseWheel(_wheel_delta, _modifiers);
00292     _wheel_delta = 0;
00293   }
00294 
00295   if (_keys.size() > 0) {
00296     ButtonActivityMap::const_iterator it;
00297     for (it = _keys.begin(); it != _keys.end(); ++it) {
00298       if (it->second) {
00299         context->ProcessKeyDown((KeyIdentifier) it->first, _modifiers);
00300       } else {
00301         context->ProcessKeyUp((KeyIdentifier) it->first, _modifiers);
00302       }
00303     }
00304     _keys.clear();
00305   }
00306 
00307   if (_repeated_keys.size() > 0) {
00308     pvector<int>::const_iterator it;
00309 
00310     for (it = _repeated_keys.begin(); it != _repeated_keys.end(); ++it) {
00311       context->ProcessKeyUp((KeyIdentifier) *it, _modifiers);
00312       context->ProcessKeyDown((KeyIdentifier) *it, _modifiers);
00313     }
00314     _repeated_keys.clear();
00315   }
00316 
00317   if (_text_input.size() > 0) {
00318     pvector<short>::const_iterator it;
00319     for (it = _text_input.begin(); it != _text_input.end(); ++it) {
00320       context->ProcessTextInput(*it);
00321     }
00322     _text_input.clear();
00323   }
00324 
00325   context->Update();
00326 }
 All Classes Functions Variables Enumerations