1/****************************************************************************
2**
3** Copyright (C) 2015 The Qt Company Ltd.
4** Contact: http://www.qt.io/licensing/
5**
6** This file is part of the Qt Gamepad module
7**
8** $QT_BEGIN_LICENSE:LGPL3$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see http://www.qt.io/terms-conditions. For further
15** information use the contact form at http://www.qt.io/contact-us.
16**
17** GNU Lesser General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU Lesser
19** General Public License version 3 as published by the Free Software
20** Foundation and appearing in the file LICENSE.LGPLv3 included in the
21** packaging of this file. Please review the following information to
22** ensure the GNU Lesser General Public License version 3 requirements
23** will be met: https://www.gnu.org/licenses/lgpl.html.
24**
25** GNU General Public License Usage
26** Alternatively, this file may be used under the terms of the GNU
27** General Public License version 2.0 or later as published by the Free
28** Software Foundation and appearing in the file LICENSE.GPL included in
29** the packaging of this file. Please review the following information to
30** ensure the GNU General Public License version 2.0 requirements will be
31** met: http://www.gnu.org/licenses/gpl-2.0.html.
32**
33** $QT_END_LICENSE$
34**
35****************************************************************************/
36
37#include "qgamepadkeynavigation.h"
38#include <QtGui/QKeyEvent>
39#include <QtGui/QGuiApplication>
40#include <QtGui/QWindow>
41#include <QtGamepad/QGamepad>
42
43#include <private/qobject_p.h>
44
45QT_BEGIN_NAMESPACE
46
47class QGamepadKeyNavigationPrivate : public QObjectPrivate
48{
49 Q_DECLARE_PUBLIC(QGamepadKeyNavigation)
50public:
51 QGamepadKeyNavigationPrivate()
52 : active(true)
53 , gamepad(nullptr)
54 , buttonL2Pressed(false)
55 , buttonR2Pressed(false)
56 {
57 }
58
59 void sendGeneratedKeyEvent(QKeyEvent *event);
60
61 bool active;
62 QGamepad *gamepad;
63 QGamepadManager *gamepadManger;
64 bool buttonL2Pressed;
65 bool buttonR2Pressed;
66 QMap<QGamepadManager::GamepadButton, Qt::Key> keyMapping;
67
68 void _q_processGamepadButtonPressEvent(int index, QGamepadManager::GamepadButton button, double value);
69 void _q_processGamepadButtonReleaseEvent(int index, QGamepadManager::GamepadButton button);
70};
71
72void QGamepadKeyNavigationPrivate::sendGeneratedKeyEvent(QKeyEvent *event)
73{
74 if (!active) {
75 delete event;
76 return;
77 }
78 const QGuiApplication *app = qApp;
79 QWindow *focusWindow = app ? app->focusWindow() : nullptr;
80 if (focusWindow)
81 QGuiApplication::sendEvent(receiver: focusWindow, event);
82}
83
84void QGamepadKeyNavigationPrivate::_q_processGamepadButtonPressEvent(int index, QGamepadManager::GamepadButton button, double value)
85{
86 Q_UNUSED(value)
87 //If a gamepad has been set then, only use the events of that gamepad
88 if (gamepad && gamepad->deviceId() != index)
89 return;
90
91 //Trigger buttons are a special case as they get multiple press events as the value changes
92 if (button == QGamepadManager::ButtonL2 && buttonL2Pressed)
93 return;
94 else
95 buttonL2Pressed = true;
96 if (button == QGamepadManager::ButtonR2 && buttonR2Pressed)
97 return;
98 else
99 buttonR2Pressed = true;
100
101 QKeyEvent *event = new QKeyEvent(QEvent::KeyPress, keyMapping[button], Qt::NoModifier);
102 sendGeneratedKeyEvent(event);
103}
104
105void QGamepadKeyNavigationPrivate::_q_processGamepadButtonReleaseEvent(int index, QGamepadManager::GamepadButton button)
106{
107 //If a gamepad has been set then, only use the events of that gamepad
108 if (gamepad && gamepad->deviceId() != index)
109 return;
110
111 //Free the trigger buttons if necessary
112 if (button == QGamepadManager::ButtonL2)
113 buttonL2Pressed = false;
114 if (button == QGamepadManager::ButtonR2)
115 buttonR2Pressed = false;
116
117 QKeyEvent *event = new QKeyEvent(QEvent::KeyRelease, keyMapping[button], Qt::NoModifier);
118 sendGeneratedKeyEvent(event);
119}
120
121/*!
122 \class QGamepadKeyNavigation
123 \inmodule QtGamepad
124 \brief Provides support for keyboard events triggered by gamepads.
125
126 QGamepadKeyNavigation provides support for keyboard events triggered by
127 gamepads.
128 */
129
130/*!
131 * Constructs a QGamepadNavigation object with the given \a parent.
132 */
133
134QGamepadKeyNavigation::QGamepadKeyNavigation(QObject *parent)
135 : QObject(*new QGamepadKeyNavigationPrivate(), parent)
136{
137 Q_D(QGamepadKeyNavigation);
138 d->gamepadManger = QGamepadManager::instance();
139
140 //Default keymap
141 d->keyMapping.insert(key: QGamepadManager::ButtonUp, value: Qt::Key_Up);
142 d->keyMapping.insert(key: QGamepadManager::ButtonDown, value: Qt::Key_Down);
143 d->keyMapping.insert(key: QGamepadManager::ButtonLeft, value: Qt::Key_Left);
144 d->keyMapping.insert(key: QGamepadManager::ButtonRight, value: Qt::Key_Right);
145 d->keyMapping.insert(key: QGamepadManager::ButtonA, value: Qt::Key_Return);
146 d->keyMapping.insert(key: QGamepadManager::ButtonB, value: Qt::Key_Back);
147 d->keyMapping.insert(key: QGamepadManager::ButtonX, value: Qt::Key_Back);
148 d->keyMapping.insert(key: QGamepadManager::ButtonY, value: Qt::Key_Back);
149 d->keyMapping.insert(key: QGamepadManager::ButtonSelect, value: Qt::Key_Back);
150 d->keyMapping.insert(key: QGamepadManager::ButtonStart, value: Qt::Key_Return);
151 d->keyMapping.insert(key: QGamepadManager::ButtonGuide, value: Qt::Key_Back);
152 d->keyMapping.insert(key: QGamepadManager::ButtonL1, value: Qt::Key_Back);
153 d->keyMapping.insert(key: QGamepadManager::ButtonR1, value: Qt::Key_Forward);
154 d->keyMapping.insert(key: QGamepadManager::ButtonL2, value: Qt::Key_Back);
155 d->keyMapping.insert(key: QGamepadManager::ButtonR2, value: Qt::Key_Forward);
156 d->keyMapping.insert(key: QGamepadManager::ButtonL3, value: Qt::Key_Back);
157 d->keyMapping.insert(key: QGamepadManager::ButtonR3, value: Qt::Key_Forward);
158
159 connect(sender: d->gamepadManger, SIGNAL(gamepadButtonPressEvent(int,QGamepadManager::GamepadButton,double)),
160 receiver: this, SLOT(_q_processGamepadButtonPressEvent(int,QGamepadManager::GamepadButton,double)));
161 connect(sender: d->gamepadManger, SIGNAL(gamepadButtonReleaseEvent(int,QGamepadManager::GamepadButton)),
162 receiver: this, SLOT(_q_processGamepadButtonReleaseEvent(int,QGamepadManager::GamepadButton)));
163}
164
165/*!
166 * Returns whether key navigation on the gamepad is active or not.
167*/
168bool QGamepadKeyNavigation::active() const
169{
170 Q_D(const QGamepadKeyNavigation);
171 return d->active;
172}
173
174/*!
175 * Returns a pointer the current QGamepad
176 */
177QGamepad *QGamepadKeyNavigation::gamepad() const
178{
179 Q_D(const QGamepadKeyNavigation);
180 return d->gamepad;
181}
182
183/*!
184 * Returns the key mapping of the Up button.
185 */
186Qt::Key QGamepadKeyNavigation::upKey() const
187{
188 Q_D(const QGamepadKeyNavigation);
189 return d->keyMapping[QGamepadManager::ButtonUp];
190}
191
192/*!
193 * Returns the key mapping of the Down button.
194 */
195Qt::Key QGamepadKeyNavigation::downKey() const
196{
197 Q_D(const QGamepadKeyNavigation);
198 return d->keyMapping[QGamepadManager::ButtonDown];
199}
200
201/*!
202 * Returns the key mapping of the Left button.
203 */
204Qt::Key QGamepadKeyNavigation::leftKey() const
205{
206 Q_D(const QGamepadKeyNavigation);
207 return d->keyMapping[QGamepadManager::ButtonLeft];
208}
209
210/*!
211 * Returns the key mapping of the Right button.
212 */
213Qt::Key QGamepadKeyNavigation::rightKey() const
214{
215 Q_D(const QGamepadKeyNavigation);
216 return d->keyMapping[QGamepadManager::ButtonRight];
217}
218
219/*!
220 * Returns the key mapping of A button.
221 */
222Qt::Key QGamepadKeyNavigation::buttonAKey() const
223{
224 Q_D(const QGamepadKeyNavigation);
225 return d->keyMapping[QGamepadManager::ButtonA];
226}
227
228/*!
229 * Returns the key mapping of the B button.
230 */
231Qt::Key QGamepadKeyNavigation::buttonBKey() const
232{
233 Q_D(const QGamepadKeyNavigation);
234 return d->keyMapping[QGamepadManager::ButtonB];
235}
236
237/*!
238 * Returns the key mapping of the X button.
239 */
240Qt::Key QGamepadKeyNavigation::buttonXKey() const
241{
242 Q_D(const QGamepadKeyNavigation);
243 return d->keyMapping[QGamepadManager::ButtonX];
244}
245
246/*!
247 * Returns the key mapping of the Y button.
248 */
249Qt::Key QGamepadKeyNavigation::buttonYKey() const
250{
251 Q_D(const QGamepadKeyNavigation);
252 return d->keyMapping[QGamepadManager::ButtonY];
253}
254
255/*!
256 * Returns the key mapping of the Select button.
257 */
258Qt::Key QGamepadKeyNavigation::buttonSelectKey() const
259{
260 Q_D(const QGamepadKeyNavigation);
261 return d->keyMapping[QGamepadManager::ButtonSelect];
262}
263
264/*!
265 * Returns the key mapping of the Start button.
266 */
267Qt::Key QGamepadKeyNavigation::buttonStartKey() const
268{
269 Q_D(const QGamepadKeyNavigation);
270 return d->keyMapping[QGamepadManager::ButtonStart];
271}
272
273/*!
274 * Returns the key mapping of the Guide button.
275 */
276Qt::Key QGamepadKeyNavigation::buttonGuideKey() const
277{
278 Q_D(const QGamepadKeyNavigation);
279 return d->keyMapping[QGamepadManager::ButtonGuide];
280}
281
282/*!
283 * Returns the key mapping of the left shoulder button.
284 */
285Qt::Key QGamepadKeyNavigation::buttonL1Key() const
286{
287 Q_D(const QGamepadKeyNavigation);
288 return d->keyMapping[QGamepadManager::ButtonL1];
289}
290
291/*!
292 * Returns the key mapping of the Right shoulder button.
293 */
294Qt::Key QGamepadKeyNavigation::buttonR1Key() const
295{
296 Q_D(const QGamepadKeyNavigation);
297 return d->keyMapping[QGamepadManager::ButtonL2];
298}
299
300/*!
301 * Returns the key mapping of the left trigger button.
302 */
303Qt::Key QGamepadKeyNavigation::buttonL2Key() const
304{
305 Q_D(const QGamepadKeyNavigation);
306 return d->keyMapping[QGamepadManager::ButtonL2];
307}
308
309/*!
310 * Returns the key mapping of the Right trigger button.
311 */
312Qt::Key QGamepadKeyNavigation::buttonR2Key() const
313{
314 Q_D(const QGamepadKeyNavigation);
315 return d->keyMapping[QGamepadManager::ButtonL2];
316}
317
318/*!
319 * Returns the key mapping of the left stick button.
320 */
321Qt::Key QGamepadKeyNavigation::buttonL3Key() const
322{
323 Q_D(const QGamepadKeyNavigation);
324 return d->keyMapping[QGamepadManager::ButtonL3];
325}
326
327/*!
328 * Returns the key mapping of the right stick button.
329 */
330Qt::Key QGamepadKeyNavigation::buttonR3Key() const
331{
332 Q_D(const QGamepadKeyNavigation);
333 return d->keyMapping[QGamepadManager::ButtonL3];
334}
335
336/*!
337 * Activates key navigation if \a isActive is true,
338 * disables it otherwise.
339 */
340void QGamepadKeyNavigation::setActive(bool isActive)
341{
342 Q_D(QGamepadKeyNavigation);
343 if (d->active != isActive) {
344 d->active = isActive;
345 emit activeChanged(isActive);
346 }
347}
348
349/*!
350 * Selects the specified \a gamepad.
351*/
352void QGamepadKeyNavigation::setGamepad(QGamepad *gamepad)
353{
354 Q_D(QGamepadKeyNavigation);
355 if (d->gamepad != gamepad) {
356 d->gamepad = gamepad;
357 emit gamepadChanged(gamepad);
358 }
359}
360
361/*!
362 * Sets the mapping of the Up button with the
363 * keycode specified in \a key.
364*/
365void QGamepadKeyNavigation::setUpKey(Qt::Key key)
366{
367 Q_D(QGamepadKeyNavigation);
368 if (d->keyMapping[QGamepadManager::ButtonUp] != key) {
369 d->keyMapping[QGamepadManager::ButtonUp] = key;
370 emit upKeyChanged(key);
371 }
372}
373
374/*!
375 * Sets the mapping of the Down button with the
376 * keycode specified in \a key.
377*/
378void QGamepadKeyNavigation::setDownKey(Qt::Key key)
379{
380 Q_D(QGamepadKeyNavigation);
381 if (d->keyMapping[QGamepadManager::ButtonDown] != key) {
382 d->keyMapping[QGamepadManager::ButtonDown] = key;
383 emit downKeyChanged(key);
384 }
385}
386
387/*!
388 * Sets the mapping of the Left button with the
389 * keycode specified in \a key.
390*/
391void QGamepadKeyNavigation::setLeftKey(Qt::Key key)
392{
393 Q_D(QGamepadKeyNavigation);
394 if (d->keyMapping[QGamepadManager::ButtonLeft] != key) {
395 d->keyMapping[QGamepadManager::ButtonLeft] = key;
396 emit leftKeyChanged(key);
397 }
398}
399
400/*!
401 * Sets the mapping of the Right button with the
402 * keycode specified in \a key.
403*/
404void QGamepadKeyNavigation::setRightKey(Qt::Key key)
405{
406 Q_D(QGamepadKeyNavigation);
407 if (d->keyMapping[QGamepadManager::ButtonRight] != key) {
408 d->keyMapping[QGamepadManager::ButtonRight] = key;
409 emit rightKeyChanged(key);
410 }
411}
412
413/*!
414 * Sets the mapping of the A button with the keycode
415 * specified in \a key.
416*/
417void QGamepadKeyNavigation::setButtonAKey(Qt::Key key)
418{
419 Q_D(QGamepadKeyNavigation);
420 if (d->keyMapping[QGamepadManager::ButtonA] != key) {
421 d->keyMapping[QGamepadManager::ButtonA] = key;
422 emit buttonAKeyChanged(key);
423 }
424}
425
426/*!
427 * Sets the mapping of the B button with the keycode
428 * specified in \a key.
429*/
430void QGamepadKeyNavigation::setButtonBKey(Qt::Key key)
431{
432 Q_D(QGamepadKeyNavigation);
433 if (d->keyMapping[QGamepadManager::ButtonB] != key) {
434 d->keyMapping[QGamepadManager::ButtonB] = key;
435 emit buttonBKeyChanged(key);
436 }
437}
438
439/*!
440 * Sets the mapping of the X button with the
441 * keycode specified in \a key.
442*/
443void QGamepadKeyNavigation::setButtonXKey(Qt::Key key)
444{
445 Q_D(QGamepadKeyNavigation);
446 if (d->keyMapping[QGamepadManager::ButtonX] != key) {
447 d->keyMapping[QGamepadManager::ButtonX] = key;
448 emit buttonXKeyChanged(key);
449 }
450}
451
452/*!
453 * Sets the mapping of the Y button with the
454 * keycode specified in \a key.
455*/
456void QGamepadKeyNavigation::setButtonYKey(Qt::Key key)
457{
458 Q_D(QGamepadKeyNavigation);
459 if (d->keyMapping[QGamepadManager::ButtonY] != key) {
460 d->keyMapping[QGamepadManager::ButtonY] = key;
461 emit buttonYKeyChanged(key);
462 }
463}
464
465/*!
466 * Sets the mapping of the Select button with the
467 * keycode specified in \a key.
468*/
469void QGamepadKeyNavigation::setButtonSelectKey(Qt::Key key)
470{
471 Q_D(QGamepadKeyNavigation);
472 if (d->keyMapping[QGamepadManager::ButtonSelect] != key) {
473 d->keyMapping[QGamepadManager::ButtonSelect] = key;
474 emit buttonSelectKeyChanged(key);
475 }
476}
477
478/*!
479 * Sets the mapping of the Start button with the
480 * keycode specified in \a key.
481*/
482void QGamepadKeyNavigation::setButtonStartKey(Qt::Key key)
483{
484 Q_D(QGamepadKeyNavigation);
485 if (d->keyMapping[QGamepadManager::ButtonStart] != key) {
486 d->keyMapping[QGamepadManager::ButtonStart] = key;
487 emit buttonStartKeyChanged(key);
488 }
489}
490
491/*!
492 * Sets the mapping of the Guide button with the keycode
493 * specified in \a key.
494*/
495void QGamepadKeyNavigation::setButtonGuideKey(Qt::Key key)
496{
497 Q_D(QGamepadKeyNavigation);
498 if (d->keyMapping[QGamepadManager::ButtonGuide] != key) {
499 d->keyMapping[QGamepadManager::ButtonGuide] = key;
500 emit buttonGuideKeyChanged(key);
501 }
502}
503
504/*!
505 * Sets the mapping of the left shoulder button with the
506 * keycode specified in \a key.
507*/
508void QGamepadKeyNavigation::setButtonL1Key(Qt::Key key)
509{
510 Q_D(QGamepadKeyNavigation);
511 if (d->keyMapping[QGamepadManager::ButtonL1] != key) {
512 d->keyMapping[QGamepadManager::ButtonL1] = key;
513 emit buttonL1KeyChanged(key);
514 }
515}
516
517/*!
518 * Sets the mapping of the right shoulder button with the
519 * keycode specified in \a key.
520*/
521void QGamepadKeyNavigation::setButtonR1Key(Qt::Key key)
522{
523 Q_D(QGamepadKeyNavigation);
524 if (d->keyMapping[QGamepadManager::ButtonR1] != key) {
525 d->keyMapping[QGamepadManager::ButtonR1] = key;
526 emit buttonR1KeyChanged(key);
527 }
528}
529
530/*!
531 * Sets the mapping of the left trigger button with the
532 * keycode specified in \a key.
533*/
534void QGamepadKeyNavigation::setButtonL2Key(Qt::Key key)
535{
536 Q_D(QGamepadKeyNavigation);
537 if (d->keyMapping[QGamepadManager::ButtonL2] != key) {
538 d->keyMapping[QGamepadManager::ButtonL2] = key;
539 emit buttonL1KeyChanged(key);
540 }
541}
542
543/*!
544 * Sets the mapping of the right trigger button with the
545 * keycode specified in \a key.
546*/
547void QGamepadKeyNavigation::setButtonR2Key(Qt::Key key)
548{
549 Q_D(QGamepadKeyNavigation);
550 if (d->keyMapping[QGamepadManager::ButtonR2] != key) {
551 d->keyMapping[QGamepadManager::ButtonR2] = key;
552 emit buttonR1KeyChanged(key);
553 }
554}
555
556/*!
557 * Sets the mapping of the left stick button with the
558 * keycode specified in \a key.
559*/
560void QGamepadKeyNavigation::setButtonL3Key(Qt::Key key)
561{
562 Q_D(QGamepadKeyNavigation);
563 if (d->keyMapping[QGamepadManager::ButtonL3] != key) {
564 d->keyMapping[QGamepadManager::ButtonL3] = key;
565 emit buttonL1KeyChanged(key);
566 }
567}
568
569/*!
570 * Sets the mapping of the right stick button with the
571 * keycode specified in \a key.
572*/
573void QGamepadKeyNavigation::setButtonR3Key(Qt::Key key)
574{
575 Q_D(QGamepadKeyNavigation);
576 if (d->keyMapping[QGamepadManager::ButtonR3] != key) {
577 d->keyMapping[QGamepadManager::ButtonR3] = key;
578 emit buttonR1KeyChanged(key);
579 }
580}
581
582QT_END_NAMESPACE
583
584#include "moc_qgamepadkeynavigation.cpp"
585

source code of qtgamepad/src/gamepad/qgamepadkeynavigation.cpp