Panda3D
Loading...
Searching...
No Matches
rocketInputHandler.cxx
Go to the documentation of this file.
1/**
2 * PANDA 3D SOFTWARE
3 * Copyright (c) Carnegie Mellon University. All rights reserved.
4 *
5 * All use of this software is subject to the terms of the revised BSD
6 * license. You should have received a copy of this license along
7 * with this source code in a file named "LICENSE."
8 *
9 * @file rocketInputHandler.cxx
10 * @author rdb
11 * @date 2011-12-20
12 */
13
14#include "rocketInputHandler.h"
15#include "buttonEventList.h"
16#include "dataGraphTraverser.h"
17#include "linmath_events.h"
19#include "keyboardButton.h"
20#include "mouseButton.h"
21
22#ifndef CPPPARSER
23#include <Rocket/Core/Input.h>
24
25using namespace Rocket::Core::Input;
26#endif
27
28TypeHandle RocketInputHandler::_type_handle;
29
30/**
31 *
32 */
33RocketInputHandler::
34RocketInputHandler(const std::string &name) :
35 DataNode(name),
36 _mouse_xy(-1),
37 _mouse_xy_changed(false),
38 _modifiers(0),
39 _wheel_delta(0)
40{
41 _pixel_xy_input = define_input("pixel_xy", EventStoreVec2::get_class_type());
42 _button_events_input = define_input("button_events", ButtonEventList::get_class_type());
43}
44
45/**
46 *
47 */
48RocketInputHandler::
49~RocketInputHandler() {
50}
51
52/**
53 * Returns the libRocket KeyIdentifier for the given ButtonHandle, or
54 * KI_UNKNOWN (0) if it wasn't known.
55 */
57get_rocket_key(const ButtonHandle handle) {
58 static pmap<int, int> keymap;
60
61 if (keymap.size() > 0) {
62 it = keymap.find(handle.get_index());
63
64 if (it == keymap.end()) {
65 return 0;
66 } else {
67 return it->second;
68 }
69 }
70
71 keymap[KeyboardButton::space().get_index()] = KI_SPACE;
72 keymap[KeyboardButton::backspace().get_index()] = KI_BACK;
73 keymap[KeyboardButton::tab().get_index()] = KI_TAB;
74 keymap[KeyboardButton::enter().get_index()] = KI_RETURN;
75 keymap[KeyboardButton::escape().get_index()] = KI_ESCAPE;
76 keymap[KeyboardButton::end().get_index()] = KI_END;
77 keymap[KeyboardButton::home().get_index()] = KI_HOME;
78 keymap[KeyboardButton::left().get_index()] = KI_LEFT;
79 keymap[KeyboardButton::up().get_index()] = KI_UP;
80 keymap[KeyboardButton::right().get_index()] = KI_RIGHT;
81 keymap[KeyboardButton::down().get_index()] = KI_DOWN;
82 keymap[KeyboardButton::insert().get_index()] = KI_INSERT;
83 keymap[KeyboardButton::del().get_index()] = KI_DELETE;
84 keymap[KeyboardButton::caps_lock().get_index()] = KI_CAPITAL;
85 keymap[KeyboardButton::f1().get_index()] = KI_F1;
86 keymap[KeyboardButton::f10().get_index()] = KI_F10;
87 keymap[KeyboardButton::f11().get_index()] = KI_F11;
88 keymap[KeyboardButton::f12().get_index()] = KI_F12;
89 keymap[KeyboardButton::f13().get_index()] = KI_F13;
90 keymap[KeyboardButton::f14().get_index()] = KI_F14;
91 keymap[KeyboardButton::f15().get_index()] = KI_F15;
92 keymap[KeyboardButton::f16().get_index()] = KI_F16;
93 keymap[KeyboardButton::f2().get_index()] = KI_F2;
94 keymap[KeyboardButton::f3().get_index()] = KI_F3;
95 keymap[KeyboardButton::f4().get_index()] = KI_F4;
96 keymap[KeyboardButton::f5().get_index()] = KI_F5;
97 keymap[KeyboardButton::f6().get_index()] = KI_F6;
98 keymap[KeyboardButton::f7().get_index()] = KI_F7;
99 keymap[KeyboardButton::f8().get_index()] = KI_F8;
100 keymap[KeyboardButton::f9().get_index()] = KI_F9;
101 keymap[KeyboardButton::help().get_index()] = KI_HELP;
102 keymap[KeyboardButton::lcontrol().get_index()] = KI_LCONTROL;
103 keymap[KeyboardButton::lshift().get_index()] = KI_LSHIFT;
104 keymap[KeyboardButton::num_lock().get_index()] = KI_NUMLOCK;
105 keymap[KeyboardButton::page_down().get_index()] = KI_NEXT;
106 keymap[KeyboardButton::page_up().get_index()] = KI_PRIOR;
107 keymap[KeyboardButton::pause().get_index()] = KI_PAUSE;
108 keymap[KeyboardButton::print_screen().get_index()] = KI_SNAPSHOT;
109 keymap[KeyboardButton::rcontrol().get_index()] = KI_RCONTROL;
110 keymap[KeyboardButton::rshift().get_index()] = KI_RSHIFT;
111 keymap[KeyboardButton::scroll_lock().get_index()] = KI_SCROLL;
112
113 // these "OEM" keys have standard mappings in Panda3D
114 keymap[KeyboardButton::ascii_key(';').get_index()] = KI_OEM_1;
115 keymap[KeyboardButton::ascii_key('=').get_index()] = KI_OEM_PLUS;
116 keymap[KeyboardButton::ascii_key(',').get_index()] = KI_OEM_COMMA;
117 keymap[KeyboardButton::ascii_key('-').get_index()] = KI_OEM_MINUS;
118 keymap[KeyboardButton::ascii_key('.').get_index()] = KI_OEM_PERIOD;
119 keymap[KeyboardButton::ascii_key('/').get_index()] = KI_OEM_2;
120 keymap[KeyboardButton::ascii_key('`').get_index()] = KI_OEM_3;
121 keymap[KeyboardButton::ascii_key('[').get_index()] = KI_OEM_4;
122 keymap[KeyboardButton::ascii_key('\\').get_index()] = KI_OEM_5;
123 keymap[KeyboardButton::ascii_key(']').get_index()] = KI_OEM_6;
124
125 // comment says this may either be "<>" or "\|", but "\" (unshifted) is
126 // handled already, and "<" is only available "shifted" on 101-keyboards, so
127 // assume it's this one...
128 keymap[KeyboardButton::ascii_key('<').get_index()] = KI_OEM_102;
129
130 for (char c = 'a'; c <= 'z'; ++c) {
131 keymap[KeyboardButton::ascii_key(c).get_index()] = (c - 'a') + KI_A;
132 }
133 for (char c = '0'; c <= '9'; ++c) {
134 keymap[KeyboardButton::ascii_key(c).get_index()] = (c - '0') + KI_0;
135 }
136
137 it = keymap.find(handle.get_index());
138 if (it != keymap.end()) {
139 return it->second;
140 }
141 return 0;
142}
143
144/**
145 * The virtual implementation of transmit_data(). This function receives an
146 * array of input parameters and should generate an array of output
147 * parameters. The input parameters may be accessed with the index numbers
148 * returned by the define_input() calls that were made earlier (presumably in
149 * the constructor); likewise, the output parameters should be set with the
150 * index numbers returned by the define_output() calls.
151 */
152void RocketInputHandler::
153do_transmit_data(DataGraphTraverser *trav, const DataNodeTransmit &input,
154 DataNodeTransmit &output) {
155 MutexHolder holder(_lock);
156
157 if (input.has_data(_pixel_xy_input)) {
158 // The mouse is within the window. Get the current mouse position.
159 const EventStoreVec2 *pixel_xy;
160 DCAST_INTO_V(pixel_xy, input.get_data(_pixel_xy_input).get_ptr());
161 LVecBase2 p = pixel_xy->get_value();
162
163 // Determine if mouse moved from last position
164 if (p != _mouse_xy) {
165 _mouse_xy_changed = true;
166 _mouse_xy = p;
167 }
168 }
169
170 ButtonEventList new_button_events;
171
172 // Look for new button events.
173 if (input.has_data(_button_events_input)) {
174 const ButtonEventList *this_button_events;
175 DCAST_INTO_V(this_button_events, input.get_data(_button_events_input).get_ptr());
176 int num_events = this_button_events->get_num_events();
177 for (int i = 0; i < num_events; i++) {
178 const ButtonEvent &be = this_button_events->get_event(i);
179
180 int rocket_key = KI_UNKNOWN;
181
182 switch (be._type) {
183 case ButtonEvent::T_down:
184 if (be._button == KeyboardButton::control()) {
185 _modifiers |= KM_CTRL;
186 } else if (be._button == KeyboardButton::shift()) {
187 _modifiers |= KM_SHIFT;
188 } else if (be._button == KeyboardButton::alt()) {
189 _modifiers |= KM_ALT;
190 } else if (be._button == KeyboardButton::meta()) {
191 _modifiers |= KM_META;
192
193 } else if (be._button == KeyboardButton::enter()) {
194 _text_input.push_back('\n');
195
196 } else if (be._button == MouseButton::wheel_up()) {
197 _wheel_delta -= 1;
198 } else if (be._button == MouseButton::wheel_down()) {
199 _wheel_delta += 1;
200
201 } else if (be._button == MouseButton::one()) {
202 _mouse_buttons[0] = true;
203 } else if (be._button == MouseButton::two()) {
204 _mouse_buttons[1] = true;
205 } else if (be._button == MouseButton::three()) {
206 _mouse_buttons[2] = true;
207 } else if (be._button == MouseButton::four()) {
208 _mouse_buttons[3] = true;
209 } else if (be._button == MouseButton::five()) {
210 _mouse_buttons[4] = true;
211 }
212
213 rocket_key = get_rocket_key(be._button);
214 if (rocket_key != KI_UNKNOWN) {
215 _keys[rocket_key] = true;
216 }
217 break;
218
219 case ButtonEvent::T_repeat:
220 if (be._button == KeyboardButton::enter()) {
221 _text_input.push_back('\n');
222 }
223
224 rocket_key = get_rocket_key(be._button);
225 if (rocket_key != KI_UNKNOWN) {
226 _repeated_keys.push_back(rocket_key);
227 }
228 break;
229
230 case ButtonEvent::T_up:
231 if (be._button == KeyboardButton::control()) {
232 _modifiers &= ~KM_CTRL;
233 } else if (be._button == KeyboardButton::shift()) {
234 _modifiers &= ~KM_SHIFT;
235 } else if (be._button == KeyboardButton::alt()) {
236 _modifiers &= ~KM_ALT;
237 } else if (be._button == KeyboardButton::meta()) {
238 _modifiers &= ~KM_META;
239
240 } else if (be._button == MouseButton::one()) {
241 _mouse_buttons[0] = false;
242 } else if (be._button == MouseButton::two()) {
243 _mouse_buttons[1] = false;
244 } else if (be._button == MouseButton::three()) {
245 _mouse_buttons[2] = false;
246 } else if (be._button == MouseButton::four()) {
247 _mouse_buttons[3] = false;
248 } else if (be._button == MouseButton::five()) {
249 _mouse_buttons[4] = false;
250 }
251
252 rocket_key = get_rocket_key(be._button);
253 if (rocket_key != KI_UNKNOWN) {
254 _keys[rocket_key] = false;
255 }
256 break;
257
258 case ButtonEvent::T_keystroke:
259 // Ignore control characters; otherwise, they actually get added to
260 // strings in the UI.
261 if (be._keycode > 0x1F && (be._keycode < 0x7F || be._keycode > 0x9F)) {
262 _text_input.push_back(be._keycode);
263 }
264 break;
265
266 case ButtonEvent::T_resume_down:
267 break;
268
269 case ButtonEvent::T_move:
270 break;
271
272 case ButtonEvent::T_candidate:
273 break;
274
275 case ButtonEvent::T_raw_down:
276 break;
277
278 case ButtonEvent::T_raw_up:
279 break;
280 }
281 }
282 }
283}
284
285/**
286 * Updates the libRocket context with the changes that we have gathered in
287 * do_transmit_data. Also calls Update() on the context.
288 */
290update_context(Rocket::Core::Context *context, int xoffs, int yoffs) {
291 MutexHolder holder(_lock);
292
293 if (_keys.size() > 0) {
294 ButtonActivityMap::const_iterator it;
295 for (it = _keys.begin(); it != _keys.end(); ++it) {
296 if (it->second) {
297 context->ProcessKeyDown((KeyIdentifier) it->first, _modifiers);
298 } else {
299 context->ProcessKeyUp((KeyIdentifier) it->first, _modifiers);
300 }
301 }
302 _keys.clear();
303 }
304
305 if (_repeated_keys.size() > 0) {
307
308 for (it = _repeated_keys.begin(); it != _repeated_keys.end(); ++it) {
309 context->ProcessKeyUp((KeyIdentifier) *it, _modifiers);
310 context->ProcessKeyDown((KeyIdentifier) *it, _modifiers);
311 }
312 _repeated_keys.clear();
313 }
314
315 if (_text_input.size() > 0) {
317 for (it = _text_input.begin(); it != _text_input.end(); ++it) {
318 context->ProcessTextInput(*it);
319 }
320 _text_input.clear();
321 }
322
323 if (_mouse_xy_changed) {
324 _mouse_xy_changed = false;
325
326 context->ProcessMouseMove(_mouse_xy.get_x() - xoffs,
327 _mouse_xy.get_y() - yoffs, _modifiers);
328 }
329
330 if (_mouse_buttons.size() > 0) {
331 ButtonActivityMap::const_iterator it;
332 for (it = _mouse_buttons.begin(); it != _mouse_buttons.end(); ++it) {
333 if (it->second) {
334 context->ProcessMouseButtonDown(it->first, _modifiers);
335 } else {
336 context->ProcessMouseButtonUp(it->first, _modifiers);
337 }
338 }
339 _mouse_buttons.clear();
340 }
341
342 if (_wheel_delta != 0) {
343 context->ProcessMouseWheel(_wheel_delta, _modifiers);
344 _wheel_delta = 0;
345 }
346
347 context->Update();
348}
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Records a set of button events that happened recently.
get_num_events
Returns the number of events in the list.
get_event
Returns the nth event in the list.
Records a button event of some kind.
Definition buttonEvent.h:49
A ButtonHandle represents a single button from any device, including keyboard buttons and mouse butto...
get_index
Returns the integer index associated with this ButtonHandle.
This object supervises the traversal of the data graph and the moving of data from one DataNode to it...
Encapsulates the data generated from (or sent into) any particular DataNode.
const EventParameter & get_data(int index) const
Extracts the data for the indicated index, if it has been stored, or the empty parameter if it has no...
bool has_data(int index) const
Returns true if the indicated parameter has been stored, false otherwise.
The fundamental type of node for the data graph.
Definition dataNode.h:52
TypedWritableReferenceCount * get_ptr() const
Retrieves a pointer to the actual value stored in the parameter.
static ButtonHandle ascii_key(char ascii_equivalent)
Returns the ButtonHandle associated with the particular ASCII character, if there is one,...
static ButtonHandle four()
Returns the ButtonHandle associated with the fourth mouse button.
static ButtonHandle wheel_up()
Returns the ButtonHandle generated when the mouse wheel is rolled one notch upwards.
static ButtonHandle one()
Returns the ButtonHandle associated with the first mouse button.
static ButtonHandle five()
Returns the ButtonHandle associated with the fifth mouse button.
static ButtonHandle two()
Returns the ButtonHandle associated with the second mouse button.
static ButtonHandle wheel_down()
Returns the ButtonHandle generated when the mouse wheel is rolled one notch downwards.
static ButtonHandle three()
Returns the ButtonHandle associated with the third mouse button.
A lightweight C++ object whose constructor calls acquire() and whose destructor calls release() on a ...
Definition mutexHolder.h:25
A handy class object for storing simple values (like integers or strings) passed along with an Event ...
Definition paramValue.h:103
get_value
Retrieves the value stored in the parameter.
Definition paramValue.h:115
static int get_rocket_key(const ButtonHandle handle)
Returns the libRocket KeyIdentifier for the given ButtonHandle, or KI_UNKNOWN (0) if it wasn't known.
void update_context(Rocket::Core::Context *context, int xoffs, int yoffs)
Updates the libRocket context with the changes that we have gathered in do_transmit_data.
TypeHandle is the identifier used to differentiate C++ class types.
Definition typeHandle.h:81
This is our own Panda specialization on the default STL map.
Definition pmap.h:49
This is our own Panda specialization on the default STL vector.
Definition pvector.h:42
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.