diff --git a/CMakeLists.txt b/CMakeLists.txt index 1acbe79d183..8171ce335ee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -457,14 +457,22 @@ if(WITH_CORE) set(HAS_KDE_QT5_FONT_STRETCH_FIX FALSE CACHE BOOL "Using KDE's Qt 5.15 fork with the QFont stretch fix") endif() - # Use Qt5SerialPort optionally for GPS - set (WITH_QTSERIALPORT TRUE CACHE BOOL "Determines whether Qt5SerialPort should be tried for GPS positioning") + # Use QtSerialPort optionally for GPS + set (WITH_QTSERIALPORT TRUE CACHE BOOL "Determines whether QtSerialPort should be tried for GPS positioning") if (WITH_QTSERIALPORT) find_package(${QT_VERSION_BASE} COMPONENTS SerialPort REQUIRED) # following variable is used in qgsconfig.h set (HAVE_QTSERIALPORT TRUE) endif() + # Use QtGamepad optionally for input control + set (WITH_QTGAMEPAD TRUE CACHE BOOL "Determines whether QtGamepad should be tried for GPS positioning") + if (WITH_QTGAMEPAD) + find_package(${QT_VERSION_BASE} COMPONENTS Gamepad REQUIRED) + # following variable is used in qgsconfig.h + set (HAVE_QTGAMEPAD TRUE) + endif() + find_package(${QT_VERSION_BASE} COMPONENTS Core Gui Widgets Network Xml Svg Concurrent Test Sql Positioning REQUIRED) if (BUILD_WITH_QT6) find_package(${QT_VERSION_BASE} COMPONENTS Core5Compat REQUIRED) diff --git a/cmake_templates/qgsconfig.h.in b/cmake_templates/qgsconfig.h.in index d96cdc39f40..a6593798fac 100644 --- a/cmake_templates/qgsconfig.h.in +++ b/cmake_templates/qgsconfig.h.in @@ -96,6 +96,8 @@ #cmakedefine HAVE_QTSERIALPORT +#cmakedefine HAVE_QTGAMEPAD + #cmakedefine HAVE_STATIC_PROVIDERS #cmakedefine HAVE_EPT diff --git a/python/CMakeLists.txt b/python/CMakeLists.txt index e9a25f4e3fe..d9547e05c55 100644 --- a/python/CMakeLists.txt +++ b/python/CMakeLists.txt @@ -226,6 +226,11 @@ if (WITH_GUI) set(SIP_DISABLE_FEATURES ${SIP_DISABLE_FEATURES} HAVE_QSCI_SIP) endif() + if(NOT WITH_QTGAMEPAD) + message(STATUS "QtGamepad not enabled - disabling bindings for derived classes") + set(SIP_DISABLE_FEATURES ${SIP_DISABLE_FEATURES} HAVE_QTGAMEPAD) + endif() + configure_file(${CMAKE_CURRENT_SOURCE_DIR}/gui/project.py.in ${CMAKE_CURRENT_BINARY_DIR}/gui/project.py @ONLY) configure_file(${CMAKE_CURRENT_SOURCE_DIR}/gui/pyproject.toml.in ${CMAKE_CURRENT_BINARY_DIR}/gui/pyproject.toml @ONLY) GENERATE_SIP_PYTHON_MODULE_CODE(qgis._gui gui/gui.sip "${sip_files_gui}" cpp_files) diff --git a/python/gui/auto_generated/inputcontroller/qgs2dgamepadcontroller.sip.in b/python/gui/auto_generated/inputcontroller/qgs2dgamepadcontroller.sip.in new file mode 100644 index 00000000000..525cd9f822c --- /dev/null +++ b/python/gui/auto_generated/inputcontroller/qgs2dgamepadcontroller.sip.in @@ -0,0 +1,353 @@ +/************************************************************************ + * This file has been generated automatically from * + * * + * src/gui/inputcontroller/qgs2dgamepadcontroller.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ + + + + + + + +// this is needed for the "convert to subclass" code below to compile +%ModuleHeaderCode +#include "qgs2dgamepadcontroller.h" +%End + + + +class QgsGamepad2DMapController : QgsAbstract2DMapController +{ +%Docstring(signature="appended") +Represents a gamepad device used for controlling a 2D map. + +.. versionadded:: 3.32 +%End + +%TypeHeaderCode +#include "qgs2dgamepadcontroller.h" +%End +%ConvertToSubClassCode + if ( qobject_cast< QgsGamepad2DMapController * >( sipCpp ) ) + + sipType = sipType_QgsGamepad2DMapController; + else + sipType = nullptr; +%End + public: + + QgsGamepad2DMapController( int gamepadDeviceId, QObject *parent /TransferThis/ = 0 ); +%Docstring +Constructor for QgsGamepad2DMapController, with the specified ``gamepadDeviceId`` and ``parent`` object. +%End + + virtual QgsGamepad2DMapController *clone() const /Factory/; + + virtual QString deviceId() const; + + + + bool isConnected() const; +%Docstring +Returns ``True`` if the gamepad is connected. +%End + + QString name() const; +%Docstring +Returns the reported name of the gamepad if one is available. +%End + + double axisLeftX() const; +%Docstring +Returns the value of the left thumbstick's X axis. The axis values range from -1.0 to 1.0. +%End + + double axisLeftY() const; +%Docstring +Returns the value of the left thumbstick's Y axis. The axis values range from -1.0 to 1.0. +%End + + double axisRightX() const; +%Docstring +Returns the value of the right thumbstick's X axis. The axis values range from -1.0 to 1.0. +%End + + double axisRightY() const; +%Docstring +Returns the value of the right thumbstick's Y axis. The axis values range from -1.0 to 1.0. +%End + + bool buttonA() const; +%Docstring +Returns the state of the A button. The value is ``True`` when pressed, and ``False`` when not pressed. +%End + + bool buttonB() const; +%Docstring +Returns the state of the B button. The value is ``True`` when pressed, and ``False`` when not pressed. +%End + + bool buttonX() const; +%Docstring +Returns the state of the X button. The value is ``True`` when pressed, and ``False`` when not pressed. +%End + + bool buttonY() const; +%Docstring +Returns the state of the Y button. The value is ``True`` when pressed, and ``False`` when not pressed. +%End + + bool buttonL1() const; +%Docstring +Returns the state of the left shoulder button. The value is ``True`` when pressed, and ``False`` when not pressed. +%End + + bool buttonR1() const; +%Docstring +Returns the state of the right shoulder button. The value is ``True`` when pressed, and ``False`` when not pressed. +%End + + double buttonL2() const; +%Docstring +Returns the value of the left trigger button. This trigger value ranges from 0.0 when not pressed to 1.0 when pressed completely. +%End + + double buttonR2() const; +%Docstring +Returns the value of the right trigger button. This trigger value ranges from 0.0 when not pressed to 1.0 when pressed completely. +%End + + bool buttonSelect() const; +%Docstring +Returns the state of the select button. The value is ``True`` when pressed, and ``False`` when not pressed. + +This button can sometimes be labeled as the Back button on some gamepads. +%End + + bool buttonStart() const; +%Docstring +Returns the state of the start button. The value is ``True`` when pressed, and ``False`` when not pressed. + +This button can sometimes be labeled as the Forward button on some gamepads. +%End + + bool buttonL3() const; +%Docstring +Returns the state of the left stick button. The value is ``True`` when pressed, and ``False`` when not pressed. + +This button is usually triggered by pressing the left joystick itself. +%End + + bool buttonR3() const; +%Docstring +Returns the state of the right stick button. The value is ``True`` when pressed, and ``False`` when not pressed. + +This button is usually triggered by pressing the right joystick itself. +%End + + bool buttonUp() const; +%Docstring +Returns the state of the direction pad up button. The value is ``True`` when pressed, and ``False`` when not pressed. +%End + + bool buttonDown() const; +%Docstring +Returns the state of the direction pad down button. The value is ``True`` when pressed, and ``False`` when not pressed. +%End + + bool buttonLeft() const; +%Docstring +Returns the state of the direction pad left button. The value is ``True`` when pressed, and ``False`` when not pressed. +%End + + bool buttonRight() const; +%Docstring +Returns the state of the direction pad right button. The value is ``True`` when pressed, and ``False`` when not pressed. +%End + + bool buttonCenter() const; +%Docstring +Returns the state of the center button. The value is ``True`` when pressed, and ``False`` when not pressed. +%End + + bool buttonGuide() const; +%Docstring +Returns the state of the center button. The value is ``True`` when pressed, and ``False`` when not pressed. + +This button is typically the one in the center of the gamepad with a logo. Not all gamepads have a guide button. +%End + + signals: + + void connectedChanged( bool value ); +%Docstring +Emitted when the connection state of the gamepad is changed. +%End + + void axisLeftXChanged( double value ); +%Docstring +Emitted when the value of the left thumbstick's X axis is changed. + +.. seealso:: :py:func:`axisLeftX` +%End + + void axisLeftYChanged( double value ); +%Docstring +Emitted when the value of the left thumbstick's Y axis is changed. + +.. seealso:: :py:func:`axisLeftY` +%End + + void axisRightXChanged( double value ); +%Docstring +Emitted when the value of the right thumbstick's X axis is changed. + +.. seealso:: :py:func:`axisRightX` +%End + + void axisRightYChanged( double value ); +%Docstring +Emitted when the value of the right thumbstick's Y axis is changed. + +.. seealso:: :py:func:`axisRightY` +%End + + void buttonAChanged( bool value ); +%Docstring +Emitted when the state of the A button is changed. + +.. seealso:: :py:func:`buttonA` +%End + + void buttonBChanged( bool value ); +%Docstring +Emitted when the state of the B button is changed. + +.. seealso:: :py:func:`buttonB` +%End + + void buttonXChanged( bool value ); +%Docstring +Emitted when the state of the X button is changed. + +.. seealso:: :py:func:`buttonX` +%End + + void buttonYChanged( bool value ); +%Docstring +Emitted when the state of the Y button is changed. + +.. seealso:: :py:func:`buttonY` +%End + + void buttonL1Changed( bool value ); +%Docstring +Emitted when the state of the left shoulder button is changed. + +.. seealso:: :py:func:`buttonL1` +%End + + void buttonR1Changed( bool value ); +%Docstring +Emitted when the state of the right shoulder button is changed. + +.. seealso:: :py:func:`buttonR1` +%End + + void buttonL2Changed( double value ); +%Docstring +Emitted when the state of the left trigger button is changed. + +.. seealso:: :py:func:`buttonL2` +%End + + void buttonR2Changed( double value ); +%Docstring +Emitted when the state of the right trigger button is changed. + +.. seealso:: :py:func:`buttonR2` +%End + + void buttonSelectChanged( bool value ); +%Docstring +Emitted when the state of the select button is changed. + +.. seealso:: :py:func:`buttonSelect` +%End + + void buttonStartChanged( bool value ); +%Docstring +Emitted when the state of the start button is changed. + +.. seealso:: :py:func:`buttonStart` +%End + + void buttonL3Changed( bool value ); +%Docstring +Emitted when the state of the left stick button is changed. + +.. seealso:: :py:func:`buttonL3` +%End + + void buttonR3Changed( bool value ); +%Docstring +Emitted when the state of the right stick button is changed. + +.. seealso:: :py:func:`buttonR3` +%End + + void buttonUpChanged( bool value ); +%Docstring +Emitted when the state of the direction pad up button is changed. + +.. seealso:: :py:func:`buttonUp` +%End + + void buttonDownChanged( bool value ); +%Docstring +Emitted when the state of the direction pad down button is changed. + +.. seealso:: :py:func:`buttonDown` +%End + + void buttonLeftChanged( bool value ); +%Docstring +Emitted when the state of the direction pad left button is changed. + +.. seealso:: :py:func:`buttonLeft` +%End + + void buttonRightChanged( bool value ); +%Docstring +Emitted when the state of the direction pad right button is changed. + +.. seealso:: :py:func:`buttonRight` +%End + + void buttonCenterChanged( bool value ); +%Docstring +Emitted when the state of the center button is changed. + +.. seealso:: :py:func:`buttonCenter` +%End + + void buttonGuideChanged( bool value ); +%Docstring +Emitted when the state of the guide button is changed. + +.. seealso:: :py:func:`buttonCenter` +%End + +}; + + +/************************************************************************ + * This file has been generated automatically from * + * * + * src/gui/inputcontroller/qgs2dgamepadcontroller.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ diff --git a/python/gui/auto_generated/inputcontroller/qgs3dgamepadcontroller.sip.in b/python/gui/auto_generated/inputcontroller/qgs3dgamepadcontroller.sip.in new file mode 100644 index 00000000000..69532d4151d --- /dev/null +++ b/python/gui/auto_generated/inputcontroller/qgs3dgamepadcontroller.sip.in @@ -0,0 +1,356 @@ +/************************************************************************ + * This file has been generated automatically from * + * * + * src/gui/inputcontroller/qgs3dgamepadcontroller.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ + + + + + + + +// this is needed for the "convert to subclass" code below to compile +%ModuleHeaderCode +#include "qgs3dgamepadcontroller.h" +%End + + + +class QgsGamepad3DMapController : QgsAbstract3DMapController +{ +%Docstring(signature="appended") +Represents a gamepad device used for controlling a 3D map. + +.. versionadded:: 3.32 +%End + +%TypeHeaderCode +#include "qgs3dgamepadcontroller.h" +%End +%ConvertToSubClassCode + if ( qobject_cast< QgsGamepad3DMapController * >( sipCpp ) ) + + sipType = sipType_QgsGamepad3DMapController; + else + sipType = nullptr; +%End + public: + + QgsGamepad3DMapController( int gamepadDeviceId, QObject *parent /TransferThis/ = 0 ); +%Docstring +Constructor for QgsGamepad3DMapController, with the specified ``gamepadDeviceId`` and ``parent`` object. +%End + + virtual QgsGamepad3DMapController *clone() const /Factory/; + + virtual QString deviceId() const; + + + + bool isConnected() const; +%Docstring +Returns ``True`` if the gamepad is connected. +%End + + QString name() const; +%Docstring +Returns the reported name of the gamepad if one is available. +%End + + double axisLeftX() const; +%Docstring +Returns the value of the left thumbstick's X axis. The axis values range from -1.0 to 1.0. +%End + + double axisLeftY() const; +%Docstring +Returns the value of the left thumbstick's Y axis. The axis values range from -1.0 to 1.0. +%End + + double axisRightX() const; +%Docstring +Returns the value of the right thumbstick's X axis. The axis values range from -1.0 to 1.0. +%End + + double axisRightY() const; +%Docstring +Returns the value of the right thumbstick's Y axis. The axis values range from -1.0 to 1.0. +%End + + bool buttonA() const; +%Docstring +Returns the state of the A button. The value is ``True`` when pressed, and ``False`` when not pressed. +%End + + bool buttonB() const; +%Docstring +Returns the state of the B button. The value is ``True`` when pressed, and ``False`` when not pressed. +%End + + bool buttonX() const; +%Docstring +Returns the state of the X button. The value is ``True`` when pressed, and ``False`` when not pressed. +%End + + bool buttonY() const; +%Docstring +Returns the state of the Y button. The value is ``True`` when pressed, and ``False`` when not pressed. +%End + + bool buttonL1() const; +%Docstring +Returns the state of the left shoulder button. The value is ``True`` when pressed, and ``False`` when not pressed. +%End + + bool buttonR1() const; +%Docstring +Returns the state of the right shoulder button. The value is ``True`` when pressed, and ``False`` when not pressed. +%End + + double buttonL2() const; +%Docstring +Returns the value of the left trigger button. This trigger value ranges from 0.0 when not pressed to 1.0 when pressed completely. +%End + + double buttonR2() const; +%Docstring +Returns the value of the right trigger button. This trigger value ranges from 0.0 when not pressed to 1.0 when pressed completely. +%End + + bool buttonSelect() const; +%Docstring +Returns the state of the select button. The value is ``True`` when pressed, and ``False`` when not pressed. + +This button can sometimes be labeled as the Back button on some gamepads. +%End + + bool buttonStart() const; +%Docstring +Returns the state of the start button. The value is ``True`` when pressed, and ``False`` when not pressed. + +This button can sometimes be labeled as the Forward button on some gamepads. +%End + + bool buttonL3() const; +%Docstring +Returns the state of the left stick button. The value is ``True`` when pressed, and ``False`` when not pressed. + +This button is usually triggered by pressing the left joystick itself. +%End + + bool buttonR3() const; +%Docstring +Returns the state of the right stick button. The value is ``True`` when pressed, and ``False`` when not pressed. + +This button is usually triggered by pressing the right joystick itself. +%End + + bool buttonUp() const; +%Docstring +Returns the state of the direction pad up button. The value is ``True`` when pressed, and ``False`` when not pressed. +%End + + bool buttonDown() const; +%Docstring +Returns the state of the direction pad down button. The value is ``True`` when pressed, and ``False`` when not pressed. +%End + + bool buttonLeft() const; +%Docstring +Returns the state of the direction pad left button. The value is ``True`` when pressed, and ``False`` when not pressed. +%End + + bool buttonRight() const; +%Docstring +Returns the state of the direction pad right button. The value is ``True`` when pressed, and ``False`` when not pressed. +%End + + bool buttonCenter() const; +%Docstring +Returns the state of the center button. The value is ``True`` when pressed, and ``False`` when not pressed. +%End + + bool buttonGuide() const; +%Docstring +Returns the state of the center button. The value is ``True`` when pressed, and ``False`` when not pressed. + +This button is typically the one in the center of the gamepad with a logo. Not all gamepads have a guide button. +%End + + + signals: + + + void connectedChanged( bool value ); +%Docstring +Emitted when the connection state of the gamepad is changed. +%End + + void axisLeftXChanged( double value ); +%Docstring +Emitted when the value of the left thumbstick's X axis is changed. + +.. seealso:: :py:func:`axisLeftX` +%End + + void axisLeftYChanged( double value ); +%Docstring +Emitted when the value of the left thumbstick's Y axis is changed. + +.. seealso:: :py:func:`axisLeftY` +%End + + void axisRightXChanged( double value ); +%Docstring +Emitted when the value of the right thumbstick's X axis is changed. + +.. seealso:: :py:func:`axisRightX` +%End + + void axisRightYChanged( double value ); +%Docstring +Emitted when the value of the right thumbstick's Y axis is changed. + +.. seealso:: :py:func:`axisRightY` +%End + + void buttonAChanged( bool value ); +%Docstring +Emitted when the state of the A button is changed. + +.. seealso:: :py:func:`buttonA` +%End + + void buttonBChanged( bool value ); +%Docstring +Emitted when the state of the B button is changed. + +.. seealso:: :py:func:`buttonB` +%End + + void buttonXChanged( bool value ); +%Docstring +Emitted when the state of the X button is changed. + +.. seealso:: :py:func:`buttonX` +%End + + void buttonYChanged( bool value ); +%Docstring +Emitted when the state of the Y button is changed. + +.. seealso:: :py:func:`buttonY` +%End + + void buttonL1Changed( bool value ); +%Docstring +Emitted when the state of the left shoulder button is changed. + +.. seealso:: :py:func:`buttonL1` +%End + + void buttonR1Changed( bool value ); +%Docstring +Emitted when the state of the right shoulder button is changed. + +.. seealso:: :py:func:`buttonR1` +%End + + void buttonL2Changed( double value ); +%Docstring +Emitted when the state of the left trigger button is changed. + +.. seealso:: :py:func:`buttonL2` +%End + + void buttonR2Changed( double value ); +%Docstring +Emitted when the state of the right trigger button is changed. + +.. seealso:: :py:func:`buttonR2` +%End + + void buttonSelectChanged( bool value ); +%Docstring +Emitted when the state of the select button is changed. + +.. seealso:: :py:func:`buttonSelect` +%End + + void buttonStartChanged( bool value ); +%Docstring +Emitted when the state of the start button is changed. + +.. seealso:: :py:func:`buttonStart` +%End + + void buttonL3Changed( bool value ); +%Docstring +Emitted when the state of the left stick button is changed. + +.. seealso:: :py:func:`buttonL3` +%End + + void buttonR3Changed( bool value ); +%Docstring +Emitted when the state of the right stick button is changed. + +.. seealso:: :py:func:`buttonR3` +%End + + void buttonUpChanged( bool value ); +%Docstring +Emitted when the state of the direction pad up button is changed. + +.. seealso:: :py:func:`buttonUp` +%End + + void buttonDownChanged( bool value ); +%Docstring +Emitted when the state of the direction pad down button is changed. + +.. seealso:: :py:func:`buttonDown` +%End + + void buttonLeftChanged( bool value ); +%Docstring +Emitted when the state of the direction pad left button is changed. + +.. seealso:: :py:func:`buttonLeft` +%End + + void buttonRightChanged( bool value ); +%Docstring +Emitted when the state of the direction pad right button is changed. + +.. seealso:: :py:func:`buttonRight` +%End + + void buttonCenterChanged( bool value ); +%Docstring +Emitted when the state of the center button is changed. + +.. seealso:: :py:func:`buttonCenter` +%End + + void buttonGuideChanged( bool value ); +%Docstring +Emitted when the state of the guide button is changed. + +.. seealso:: :py:func:`buttonCenter` +%End + +}; + + + +/************************************************************************ + * This file has been generated automatically from * + * * + * src/gui/inputcontroller/qgs3dgamepadcontroller.h * + * * + * Do not edit manually ! Edit header and run scripts/sipify.pl again * + ************************************************************************/ diff --git a/python/gui/gui.sip.in b/python/gui/gui.sip.in index ca7d78d471f..6c334a7a753 100644 --- a/python/gui/gui.sip.in +++ b/python/gui/gui.sip.in @@ -4,6 +4,7 @@ ${DEFAULTDOCSTRINGSIGNATURE} %Feature HAVE_QSCI_SIP +%Feature HAVE_QTGAMEPAD %Import core/core.sip diff --git a/python/gui/gui_auto.sip b/python/gui/gui_auto.sip index 9643c226d0f..b74d1f47469 100644 --- a/python/gui/gui_auto.sip +++ b/python/gui/gui_auto.sip @@ -353,7 +353,13 @@ %Include auto_generated/history/qgshistorywidget.sip %Include auto_generated/history/qgshistorywidgetcontext.sip %Include auto_generated/inputcontroller/qgs2dmapcontroller.sip +%If ( HAVE_QTGAMEPAD ) +%Include auto_generated/inputcontroller/qgs2dgamepadcontroller.sip +%End %Include auto_generated/inputcontroller/qgs3dmapcontroller.sip +%If ( HAVE_QTGAMEPAD ) +%Include auto_generated/inputcontroller/qgs3dgamepadcontroller.sip +%End %Include auto_generated/inputcontroller/qgsabstractinputcontroller.sip %Include auto_generated/inputcontroller/qgsinputcontrollermanager.sip %Include auto_generated/labeling/qgslabellineanchorwidget.sip diff --git a/src/gui/CMakeLists.txt b/src/gui/CMakeLists.txt index ee59d7f790b..e71699ce30c 100644 --- a/src/gui/CMakeLists.txt +++ b/src/gui/CMakeLists.txt @@ -246,7 +246,9 @@ set(QGIS_GUI_SRCS history/qgshistorywidgetcontext.cpp inputcontroller/qgs2dmapcontroller.cpp + inputcontroller/qgs2dgamepadcontroller.cpp inputcontroller/qgs3dmapcontroller.cpp + inputcontroller/qgs3dgamepadcontroller.cpp inputcontroller/qgsabstractinputcontroller.cpp inputcontroller/qgsinputcontrollermanager.cpp @@ -1175,7 +1177,9 @@ set(QGIS_GUI_HDRS history/qgshistorywidgetcontext.h inputcontroller/qgs2dmapcontroller.h + inputcontroller/qgs2dgamepadcontroller.h inputcontroller/qgs3dmapcontroller.h + inputcontroller/qgs3dgamepadcontroller.h inputcontroller/qgsabstractinputcontroller.h inputcontroller/qgsinputcontrollermanager.h @@ -1701,6 +1705,12 @@ if (BUILD_WITH_QT6) ) endif() +if (WITH_QTGAMEPAD) + target_link_libraries(qgis_gui + ${QT_VERSION_BASE}::Gamepad + ) +endif() + if (FORCE_STATIC_LIBS) target_link_libraries(qgis_gui provider_wms_gui_a diff --git a/src/gui/inputcontroller/qgs2dgamepadcontroller.cpp b/src/gui/inputcontroller/qgs2dgamepadcontroller.cpp new file mode 100644 index 00000000000..ba2b278ef66 --- /dev/null +++ b/src/gui/inputcontroller/qgs2dgamepadcontroller.cpp @@ -0,0 +1,188 @@ +/*************************************************************************** + qgs2dgamepadcontroller.cpp + --------------------- + begin : March 2023 + copyright : (C) 2023 by Nyall Dawson + email : nyall dot dawson at gmail dot com + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "qgs2dgamepadcontroller.h" + +#ifdef HAVE_QTGAMEPAD + +#include + +QgsGamepad2DMapController::QgsGamepad2DMapController( int gamepadDeviceId, QObject *parent ) + : QgsAbstract2DMapController( parent ) + , mGamepadDeviceId( gamepadDeviceId ) +{ + mGamepad = new QGamepad( gamepadDeviceId, this ); + + // proxy raw signals for interested PyQGIS + connect( mGamepad, &QGamepad::connectedChanged, this, &QgsGamepad2DMapController::connectedChanged ); + connect( mGamepad, &QGamepad::axisLeftXChanged, this, &QgsGamepad2DMapController::axisLeftXChanged ); + connect( mGamepad, &QGamepad::axisLeftYChanged, this, &QgsGamepad2DMapController::axisLeftYChanged ); + connect( mGamepad, &QGamepad::axisRightXChanged, this, &QgsGamepad2DMapController::axisRightXChanged ); + connect( mGamepad, &QGamepad::axisRightYChanged, this, &QgsGamepad2DMapController::axisRightYChanged ); + connect( mGamepad, &QGamepad::buttonAChanged, this, &QgsGamepad2DMapController::buttonAChanged ); + connect( mGamepad, &QGamepad::buttonBChanged, this, &QgsGamepad2DMapController::buttonBChanged ); + connect( mGamepad, &QGamepad::buttonXChanged, this, &QgsGamepad2DMapController::buttonXChanged ); + connect( mGamepad, &QGamepad::buttonYChanged, this, &QgsGamepad2DMapController::buttonYChanged ); + connect( mGamepad, &QGamepad::buttonL1Changed, this, &QgsGamepad2DMapController::buttonL1Changed ); + connect( mGamepad, &QGamepad::buttonR1Changed, this, &QgsGamepad2DMapController::buttonR1Changed ); + connect( mGamepad, &QGamepad::buttonL2Changed, this, &QgsGamepad2DMapController::buttonL2Changed ); + connect( mGamepad, &QGamepad::buttonR2Changed, this, &QgsGamepad2DMapController::buttonR2Changed ); + connect( mGamepad, &QGamepad::buttonSelectChanged, this, &QgsGamepad2DMapController::buttonSelectChanged ); + connect( mGamepad, &QGamepad::buttonStartChanged, this, &QgsGamepad2DMapController::buttonStartChanged ); + connect( mGamepad, &QGamepad::buttonL3Changed, this, &QgsGamepad2DMapController::buttonL3Changed ); + connect( mGamepad, &QGamepad::buttonR3Changed, this, &QgsGamepad2DMapController::buttonR3Changed ); + connect( mGamepad, &QGamepad::buttonUpChanged, this, &QgsGamepad2DMapController::buttonUpChanged ); + connect( mGamepad, &QGamepad::buttonDownChanged, this, &QgsGamepad2DMapController::buttonDownChanged ); + connect( mGamepad, &QGamepad::buttonLeftChanged, this, &QgsGamepad2DMapController::buttonLeftChanged ); + connect( mGamepad, &QGamepad::buttonRightChanged, this, &QgsGamepad2DMapController::buttonRightChanged ); + connect( mGamepad, &QGamepad::buttonCenterChanged, this, &QgsGamepad2DMapController::buttonCenterChanged ); + connect( mGamepad, &QGamepad::buttonGuideChanged, this, &QgsGamepad2DMapController::buttonGuideChanged ); + + // also here we would make connections to the 2D map controller signals like zoomMap, depending on some + // reasonable defaults and user defined QSettings + +} + +QgsGamepad2DMapController *QgsGamepad2DMapController::clone() const +{ + return new QgsGamepad2DMapController( mGamepadDeviceId ); +} + +QString QgsGamepad2DMapController::deviceId() const +{ + return QStringLiteral( "gamepad2d:%1" ).arg( mGamepadDeviceId ); +} + +bool QgsGamepad2DMapController::isConnected() const +{ + return mGamepad->isConnected(); +} + +QString QgsGamepad2DMapController::name() const +{ + return mGamepad->name(); +} + +double QgsGamepad2DMapController::axisLeftX() const +{ + return mGamepad->axisLeftX(); +} + +double QgsGamepad2DMapController::axisLeftY() const +{ + return mGamepad->axisLeftY(); +} + +double QgsGamepad2DMapController::axisRightX() const +{ + return mGamepad->axisRightX(); +} + +double QgsGamepad2DMapController::axisRightY() const +{ + return mGamepad->axisRightY(); +} + +bool QgsGamepad2DMapController::buttonA() const +{ + return mGamepad->buttonA(); +} + +bool QgsGamepad2DMapController::buttonB() const +{ + return mGamepad->buttonB(); +} + +bool QgsGamepad2DMapController::buttonX() const +{ + return mGamepad->buttonX(); +} + +bool QgsGamepad2DMapController::buttonY() const +{ + return mGamepad->buttonY(); +} + +bool QgsGamepad2DMapController::buttonL1() const +{ + return mGamepad->buttonL1(); +} + +bool QgsGamepad2DMapController::buttonR1() const +{ + return mGamepad->buttonR1(); +} + +double QgsGamepad2DMapController::buttonL2() const +{ + return mGamepad->buttonL2(); +} + +double QgsGamepad2DMapController::buttonR2() const +{ + return mGamepad->buttonR2(); +} + +bool QgsGamepad2DMapController::buttonSelect() const +{ + return mGamepad->buttonSelect(); +} + +bool QgsGamepad2DMapController::buttonStart() const +{ + return mGamepad->buttonStart(); +} + +bool QgsGamepad2DMapController::buttonL3() const +{ + return mGamepad->buttonL3(); +} + +bool QgsGamepad2DMapController::buttonR3() const +{ + return mGamepad->buttonR3(); +} + +bool QgsGamepad2DMapController::buttonUp() const +{ + return mGamepad->buttonUp(); +} + +bool QgsGamepad2DMapController::buttonDown() const +{ + return mGamepad->buttonDown(); +} + +bool QgsGamepad2DMapController::buttonLeft() const +{ + return mGamepad->buttonLeft(); +} + +bool QgsGamepad2DMapController::buttonRight() const +{ + return mGamepad->buttonRight(); +} + +bool QgsGamepad2DMapController::buttonCenter() const +{ + return mGamepad->buttonCenter(); +} + +bool QgsGamepad2DMapController::buttonGuide() const +{ + return mGamepad->buttonGuide(); +} + +#endif diff --git a/src/gui/inputcontroller/qgs2dgamepadcontroller.h b/src/gui/inputcontroller/qgs2dgamepadcontroller.h new file mode 100644 index 00000000000..cad68884f3c --- /dev/null +++ b/src/gui/inputcontroller/qgs2dgamepadcontroller.h @@ -0,0 +1,375 @@ +/*************************************************************************** + qgs2dgamepadcontroller.h + --------------------- + begin : March 2023 + copyright : (C) 2023 by Nyall Dawson + email : nyall dot dawson at gmail dot com + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef QGS2DGAMEPADCONTROLLER_H +#define QGS2DGAMEPADCONTROLLER_H + +#include "qgis_sip.h" +#include "qgsconfig.h" + +SIP_IF_MODULE( HAVE_QTGAMEPAD ) + +#ifdef HAVE_QTGAMEPAD + +#include "qgis_gui.h" +#include "qgis.h" +#include "qgs2dmapcontroller.h" + +#include + +#ifdef SIP_RUN +// this is needed for the "convert to subclass" code below to compile +% ModuleHeaderCode +#include "qgs2dgamepadcontroller.h" +% End +#endif + +class QGamepad; + + +/** + * \ingroup gui + * \class QgsGamepad2DMapController + * \brief Represents a gamepad device used for controlling a 2D map. + * + * \since QGIS 3.32 + */ +class GUI_EXPORT QgsGamepad2DMapController : public QgsAbstract2DMapController +{ + Q_OBJECT + +#ifdef SIP_RUN + SIP_CONVERT_TO_SUBCLASS_CODE + if ( qobject_cast< QgsGamepad2DMapController * >( sipCpp ) ) + + sipType = sipType_QgsGamepad2DMapController; + else + sipType = nullptr; + SIP_END +#endif + + public: + + /** + * Constructor for QgsGamepad2DMapController, with the specified \a gamepadDeviceId and \a parent object. + */ + QgsGamepad2DMapController( int gamepadDeviceId, QObject *parent SIP_TRANSFERTHIS = nullptr ); + + QgsGamepad2DMapController *clone() const override SIP_FACTORY; + QString deviceId() const override; + + // proxy QGamepad signals and properties here, as QGamepad isn't accessible from Python. + // Ideally we would share these with QgsGamepad3DMapController, but that would create a diamond + // inheritance + + /** + * Returns TRUE if the gamepad is connected. + */ + bool isConnected() const; + + /** + * Returns the reported name of the gamepad if one is available. + */ + QString name() const; + + /** + * Returns the value of the left thumbstick's X axis. The axis values range from -1.0 to 1.0. + */ + double axisLeftX() const; + + /** + * Returns the value of the left thumbstick's Y axis. The axis values range from -1.0 to 1.0. + */ + double axisLeftY() const; + + /** + * Returns the value of the right thumbstick's X axis. The axis values range from -1.0 to 1.0. + */ + double axisRightX() const; + + /** + * Returns the value of the right thumbstick's Y axis. The axis values range from -1.0 to 1.0. + */ + double axisRightY() const; + + /** + * Returns the state of the A button. The value is TRUE when pressed, and FALSE when not pressed. + */ + bool buttonA() const; + + /** + * Returns the state of the B button. The value is TRUE when pressed, and FALSE when not pressed. + */ + bool buttonB() const; + + /** + * Returns the state of the X button. The value is TRUE when pressed, and FALSE when not pressed. + */ + bool buttonX() const; + + /** + * Returns the state of the Y button. The value is TRUE when pressed, and FALSE when not pressed. + */ + bool buttonY() const; + + /** + * Returns the state of the left shoulder button. The value is TRUE when pressed, and FALSE when not pressed. + */ + bool buttonL1() const; + + /** + * Returns the state of the right shoulder button. The value is TRUE when pressed, and FALSE when not pressed. + */ + bool buttonR1() const; + + /** + * Returns the value of the left trigger button. This trigger value ranges from 0.0 when not pressed to 1.0 when pressed completely. + */ + double buttonL2() const; + + /** + * Returns the value of the right trigger button. This trigger value ranges from 0.0 when not pressed to 1.0 when pressed completely. + */ + double buttonR2() const; + + /** + * Returns the state of the select button. The value is TRUE when pressed, and FALSE when not pressed. + * + * This button can sometimes be labeled as the Back button on some gamepads. + */ + bool buttonSelect() const; + + /** + * Returns the state of the start button. The value is TRUE when pressed, and FALSE when not pressed. + * + * This button can sometimes be labeled as the Forward button on some gamepads. + */ + bool buttonStart() const; + + /** + * Returns the state of the left stick button. The value is TRUE when pressed, and FALSE when not pressed. + * + * This button is usually triggered by pressing the left joystick itself. + */ + bool buttonL3() const; + + /** + * Returns the state of the right stick button. The value is TRUE when pressed, and FALSE when not pressed. + * + * This button is usually triggered by pressing the right joystick itself. + */ + bool buttonR3() const; + + /** + * Returns the state of the direction pad up button. The value is TRUE when pressed, and FALSE when not pressed. + */ + bool buttonUp() const; + + /** + * Returns the state of the direction pad down button. The value is TRUE when pressed, and FALSE when not pressed. + */ + bool buttonDown() const; + + /** + * Returns the state of the direction pad left button. The value is TRUE when pressed, and FALSE when not pressed. + */ + bool buttonLeft() const; + + /** + * Returns the state of the direction pad right button. The value is TRUE when pressed, and FALSE when not pressed. + */ + bool buttonRight() const; + + /** + * Returns the state of the center button. The value is TRUE when pressed, and FALSE when not pressed. + */ + bool buttonCenter() const; + + /** + * Returns the state of the center button. The value is TRUE when pressed, and FALSE when not pressed. + * + * This button is typically the one in the center of the gamepad with a logo. Not all gamepads have a guide button. + */ + bool buttonGuide() const; + + signals: + + /** + * Emitted when the connection state of the gamepad is changed. + */ + void connectedChanged( bool value ); + + /** + * Emitted when the value of the left thumbstick's X axis is changed. + * + * \see axisLeftX() + */ + void axisLeftXChanged( double value ); + + /** + * Emitted when the value of the left thumbstick's Y axis is changed. + * + * \see axisLeftY() + */ + void axisLeftYChanged( double value ); + + /** + * Emitted when the value of the right thumbstick's X axis is changed. + * + * \see axisRightX() + */ + void axisRightXChanged( double value ); + + /** + * Emitted when the value of the right thumbstick's Y axis is changed. + * + * \see axisRightY() + */ + void axisRightYChanged( double value ); + + /** + * Emitted when the state of the A button is changed. + * + * \see buttonA() + */ + void buttonAChanged( bool value ); + + /** + * Emitted when the state of the B button is changed. + * + * \see buttonB() + */ + void buttonBChanged( bool value ); + + /** + * Emitted when the state of the X button is changed. + * + * \see buttonX() + */ + void buttonXChanged( bool value ); + + /** + * Emitted when the state of the Y button is changed. + * + * \see buttonY() + */ + void buttonYChanged( bool value ); + + /** + * Emitted when the state of the left shoulder button is changed. + * + * \see buttonL1() + */ + void buttonL1Changed( bool value ); + + /** + * Emitted when the state of the right shoulder button is changed. + * + * \see buttonR1() + */ + void buttonR1Changed( bool value ); + + /** + * Emitted when the state of the left trigger button is changed. + * + * \see buttonL2() + */ + void buttonL2Changed( double value ); + + /** + * Emitted when the state of the right trigger button is changed. + * + * \see buttonR2() + */ + void buttonR2Changed( double value ); + + /** + * Emitted when the state of the select button is changed. + * + * \see buttonSelect() + */ + void buttonSelectChanged( bool value ); + + /** + * Emitted when the state of the start button is changed. + * + * \see buttonStart() + */ + void buttonStartChanged( bool value ); + + /** + * Emitted when the state of the left stick button is changed. + * + * \see buttonL3() + */ + void buttonL3Changed( bool value ); + + /** + * Emitted when the state of the right stick button is changed. + * + * \see buttonR3() + */ + void buttonR3Changed( bool value ); + + /** + * Emitted when the state of the direction pad up button is changed. + * + * \see buttonUp() + */ + void buttonUpChanged( bool value ); + + /** + * Emitted when the state of the direction pad down button is changed. + * + * \see buttonDown() + */ + void buttonDownChanged( bool value ); + + /** + * Emitted when the state of the direction pad left button is changed. + * + * \see buttonLeft() + */ + void buttonLeftChanged( bool value ); + + /** + * Emitted when the state of the direction pad right button is changed. + * + * \see buttonRight() + */ + void buttonRightChanged( bool value ); + + /** + * Emitted when the state of the center button is changed. + * + * \see buttonCenter() + */ + void buttonCenterChanged( bool value ); + + /** + * Emitted when the state of the guide button is changed. + * + * \see buttonCenter() + */ + void buttonGuideChanged( bool value ); + + private: + int mGamepadDeviceId = -1; + QPointer< QGamepad> mGamepad; +}; + +#endif + +#endif // QGS2DGAMEPADCONTROLLER_H diff --git a/src/gui/inputcontroller/qgs3dgamepadcontroller.cpp b/src/gui/inputcontroller/qgs3dgamepadcontroller.cpp new file mode 100644 index 00000000000..958b45f9a8e --- /dev/null +++ b/src/gui/inputcontroller/qgs3dgamepadcontroller.cpp @@ -0,0 +1,187 @@ +/*************************************************************************** + qgs3dgamepadcontroller.cpp + --------------------- + begin : March 2023 + copyright : (C) 2023 by Nyall Dawson + email : nyall dot dawson at gmail dot com + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#include "qgs3dgamepadcontroller.h" + +#ifdef HAVE_QTGAMEPAD + +#include + +QgsGamepad3DMapController::QgsGamepad3DMapController( int gamepadDeviceId, QObject *parent ) + : QgsAbstract3DMapController( parent ) + , mGamepadDeviceId( gamepadDeviceId ) +{ + mGamepad = new QGamepad( gamepadDeviceId, this ); + + // proxy raw signals for interested PyQGIS + connect( mGamepad, &QGamepad::connectedChanged, this, &QgsGamepad3DMapController::connectedChanged ); + connect( mGamepad, &QGamepad::axisLeftXChanged, this, &QgsGamepad3DMapController::axisLeftXChanged ); + connect( mGamepad, &QGamepad::axisLeftYChanged, this, &QgsGamepad3DMapController::axisLeftYChanged ); + connect( mGamepad, &QGamepad::axisRightXChanged, this, &QgsGamepad3DMapController::axisRightXChanged ); + connect( mGamepad, &QGamepad::axisRightYChanged, this, &QgsGamepad3DMapController::axisRightYChanged ); + connect( mGamepad, &QGamepad::buttonAChanged, this, &QgsGamepad3DMapController::buttonAChanged ); + connect( mGamepad, &QGamepad::buttonBChanged, this, &QgsGamepad3DMapController::buttonBChanged ); + connect( mGamepad, &QGamepad::buttonXChanged, this, &QgsGamepad3DMapController::buttonXChanged ); + connect( mGamepad, &QGamepad::buttonYChanged, this, &QgsGamepad3DMapController::buttonYChanged ); + connect( mGamepad, &QGamepad::buttonL1Changed, this, &QgsGamepad3DMapController::buttonL1Changed ); + connect( mGamepad, &QGamepad::buttonR1Changed, this, &QgsGamepad3DMapController::buttonR1Changed ); + connect( mGamepad, &QGamepad::buttonL2Changed, this, &QgsGamepad3DMapController::buttonL2Changed ); + connect( mGamepad, &QGamepad::buttonR2Changed, this, &QgsGamepad3DMapController::buttonR2Changed ); + connect( mGamepad, &QGamepad::buttonSelectChanged, this, &QgsGamepad3DMapController::buttonSelectChanged ); + connect( mGamepad, &QGamepad::buttonStartChanged, this, &QgsGamepad3DMapController::buttonStartChanged ); + connect( mGamepad, &QGamepad::buttonL3Changed, this, &QgsGamepad3DMapController::buttonL3Changed ); + connect( mGamepad, &QGamepad::buttonR3Changed, this, &QgsGamepad3DMapController::buttonR3Changed ); + connect( mGamepad, &QGamepad::buttonUpChanged, this, &QgsGamepad3DMapController::buttonUpChanged ); + connect( mGamepad, &QGamepad::buttonDownChanged, this, &QgsGamepad3DMapController::buttonDownChanged ); + connect( mGamepad, &QGamepad::buttonLeftChanged, this, &QgsGamepad3DMapController::buttonLeftChanged ); + connect( mGamepad, &QGamepad::buttonRightChanged, this, &QgsGamepad3DMapController::buttonRightChanged ); + connect( mGamepad, &QGamepad::buttonCenterChanged, this, &QgsGamepad3DMapController::buttonCenterChanged ); + connect( mGamepad, &QGamepad::buttonGuideChanged, this, &QgsGamepad3DMapController::buttonGuideChanged ); + + // also here we would make connections to the 2D map controller signals like zoomMap, depending on some + // reasonable defaults and user defined QSettings +} + +QgsGamepad3DMapController *QgsGamepad3DMapController::clone() const +{ + return new QgsGamepad3DMapController( mGamepadDeviceId ); +} + +QString QgsGamepad3DMapController::deviceId() const +{ + return QStringLiteral( "gamepad3d:%1" ).arg( mGamepadDeviceId ); +} + +bool QgsGamepad3DMapController::isConnected() const +{ + return mGamepad->isConnected(); +} + +QString QgsGamepad3DMapController::name() const +{ + return mGamepad->name(); +} + +double QgsGamepad3DMapController::axisLeftX() const +{ + return mGamepad->axisLeftX(); +} + +double QgsGamepad3DMapController::axisLeftY() const +{ + return mGamepad->axisLeftY(); +} + +double QgsGamepad3DMapController::axisRightX() const +{ + return mGamepad->axisRightX(); +} + +double QgsGamepad3DMapController::axisRightY() const +{ + return mGamepad->axisRightY(); +} + +bool QgsGamepad3DMapController::buttonA() const +{ + return mGamepad->buttonA(); +} + +bool QgsGamepad3DMapController::buttonB() const +{ + return mGamepad->buttonB(); +} + +bool QgsGamepad3DMapController::buttonX() const +{ + return mGamepad->buttonX(); +} + +bool QgsGamepad3DMapController::buttonY() const +{ + return mGamepad->buttonY(); +} + +bool QgsGamepad3DMapController::buttonL1() const +{ + return mGamepad->buttonL1(); +} + +bool QgsGamepad3DMapController::buttonR1() const +{ + return mGamepad->buttonR1(); +} + +double QgsGamepad3DMapController::buttonL2() const +{ + return mGamepad->buttonL2(); +} + +double QgsGamepad3DMapController::buttonR2() const +{ + return mGamepad->buttonR2(); +} + +bool QgsGamepad3DMapController::buttonSelect() const +{ + return mGamepad->buttonSelect(); +} + +bool QgsGamepad3DMapController::buttonStart() const +{ + return mGamepad->buttonStart(); +} + +bool QgsGamepad3DMapController::buttonL3() const +{ + return mGamepad->buttonL3(); +} + +bool QgsGamepad3DMapController::buttonR3() const +{ + return mGamepad->buttonR3(); +} + +bool QgsGamepad3DMapController::buttonUp() const +{ + return mGamepad->buttonUp(); +} + +bool QgsGamepad3DMapController::buttonDown() const +{ + return mGamepad->buttonDown(); +} + +bool QgsGamepad3DMapController::buttonLeft() const +{ + return mGamepad->buttonLeft(); +} + +bool QgsGamepad3DMapController::buttonRight() const +{ + return mGamepad->buttonRight(); +} + +bool QgsGamepad3DMapController::buttonCenter() const +{ + return mGamepad->buttonCenter(); +} + +bool QgsGamepad3DMapController::buttonGuide() const +{ + return mGamepad->buttonGuide(); +} + +#endif diff --git a/src/gui/inputcontroller/qgs3dgamepadcontroller.h b/src/gui/inputcontroller/qgs3dgamepadcontroller.h new file mode 100644 index 00000000000..15c3db75a1b --- /dev/null +++ b/src/gui/inputcontroller/qgs3dgamepadcontroller.h @@ -0,0 +1,379 @@ +/*************************************************************************** + qgs3dgamepadcontroller.h + --------------------- + begin : March 2023 + copyright : (C) 2023 by Nyall Dawson + email : nyall dot dawson at gmail dot com + *************************************************************************** + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + ***************************************************************************/ + +#ifndef QGS3DGAMEPADCONTROLLER_H +#define QGS3DGAMEPADCONTROLLER_H + +#include "qgis_sip.h" +#include "qgsconfig.h" + +SIP_IF_MODULE( HAVE_QTGAMEPAD ) + +#ifdef HAVE_QTGAMEPAD + +#include "qgis_gui.h" +#include "qgis.h" +#include "qgs3dmapcontroller.h" + +#include + +#ifdef SIP_RUN +// this is needed for the "convert to subclass" code below to compile +% ModuleHeaderCode +#include "qgs3dgamepadcontroller.h" +% End +#endif + +class QGamepad; + + +/** + * \ingroup gui + * \class QgsGamepad3DMapController + * \brief Represents a gamepad device used for controlling a 3D map. + * + * \since QGIS 3.32 + */ +class GUI_EXPORT QgsGamepad3DMapController : public QgsAbstract3DMapController +{ + Q_OBJECT + +#ifdef SIP_RUN + SIP_CONVERT_TO_SUBCLASS_CODE + if ( qobject_cast< QgsGamepad3DMapController * >( sipCpp ) ) + + sipType = sipType_QgsGamepad3DMapController; + else + sipType = nullptr; + SIP_END +#endif + + public: + + /** + * Constructor for QgsGamepad3DMapController, with the specified \a gamepadDeviceId and \a parent object. + */ + QgsGamepad3DMapController( int gamepadDeviceId, QObject *parent SIP_TRANSFERTHIS = nullptr ); + + QgsGamepad3DMapController *clone() const override SIP_FACTORY; + QString deviceId() const override; + + // proxy QGamepad signals and properties here, as QGamepad isn't accessible from Python. + // Ideally we would share these with QgsGamepad3DMapController, but that would create a diamond + // inheritance + + /** + * Returns TRUE if the gamepad is connected. + */ + bool isConnected() const; + + /** + * Returns the reported name of the gamepad if one is available. + */ + QString name() const; + + /** + * Returns the value of the left thumbstick's X axis. The axis values range from -1.0 to 1.0. + */ + double axisLeftX() const; + + /** + * Returns the value of the left thumbstick's Y axis. The axis values range from -1.0 to 1.0. + */ + double axisLeftY() const; + + /** + * Returns the value of the right thumbstick's X axis. The axis values range from -1.0 to 1.0. + */ + double axisRightX() const; + + /** + * Returns the value of the right thumbstick's Y axis. The axis values range from -1.0 to 1.0. + */ + double axisRightY() const; + + /** + * Returns the state of the A button. The value is TRUE when pressed, and FALSE when not pressed. + */ + bool buttonA() const; + + /** + * Returns the state of the B button. The value is TRUE when pressed, and FALSE when not pressed. + */ + bool buttonB() const; + + /** + * Returns the state of the X button. The value is TRUE when pressed, and FALSE when not pressed. + */ + bool buttonX() const; + + /** + * Returns the state of the Y button. The value is TRUE when pressed, and FALSE when not pressed. + */ + bool buttonY() const; + + /** + * Returns the state of the left shoulder button. The value is TRUE when pressed, and FALSE when not pressed. + */ + bool buttonL1() const; + + /** + * Returns the state of the right shoulder button. The value is TRUE when pressed, and FALSE when not pressed. + */ + bool buttonR1() const; + + /** + * Returns the value of the left trigger button. This trigger value ranges from 0.0 when not pressed to 1.0 when pressed completely. + */ + double buttonL2() const; + + /** + * Returns the value of the right trigger button. This trigger value ranges from 0.0 when not pressed to 1.0 when pressed completely. + */ + double buttonR2() const; + + /** + * Returns the state of the select button. The value is TRUE when pressed, and FALSE when not pressed. + * + * This button can sometimes be labeled as the Back button on some gamepads. + */ + bool buttonSelect() const; + + /** + * Returns the state of the start button. The value is TRUE when pressed, and FALSE when not pressed. + * + * This button can sometimes be labeled as the Forward button on some gamepads. + */ + bool buttonStart() const; + + /** + * Returns the state of the left stick button. The value is TRUE when pressed, and FALSE when not pressed. + * + * This button is usually triggered by pressing the left joystick itself. + */ + bool buttonL3() const; + + /** + * Returns the state of the right stick button. The value is TRUE when pressed, and FALSE when not pressed. + * + * This button is usually triggered by pressing the right joystick itself. + */ + bool buttonR3() const; + + /** + * Returns the state of the direction pad up button. The value is TRUE when pressed, and FALSE when not pressed. + */ + bool buttonUp() const; + + /** + * Returns the state of the direction pad down button. The value is TRUE when pressed, and FALSE when not pressed. + */ + bool buttonDown() const; + + /** + * Returns the state of the direction pad left button. The value is TRUE when pressed, and FALSE when not pressed. + */ + bool buttonLeft() const; + + /** + * Returns the state of the direction pad right button. The value is TRUE when pressed, and FALSE when not pressed. + */ + bool buttonRight() const; + + /** + * Returns the state of the center button. The value is TRUE when pressed, and FALSE when not pressed. + */ + bool buttonCenter() const; + + /** + * Returns the state of the center button. The value is TRUE when pressed, and FALSE when not pressed. + * + * This button is typically the one in the center of the gamepad with a logo. Not all gamepads have a guide button. + */ + bool buttonGuide() const; + + + signals: + + + /** + * Emitted when the connection state of the gamepad is changed. + */ + void connectedChanged( bool value ); + + /** + * Emitted when the value of the left thumbstick's X axis is changed. + * + * \see axisLeftX() + */ + void axisLeftXChanged( double value ); + + /** + * Emitted when the value of the left thumbstick's Y axis is changed. + * + * \see axisLeftY() + */ + void axisLeftYChanged( double value ); + + /** + * Emitted when the value of the right thumbstick's X axis is changed. + * + * \see axisRightX() + */ + void axisRightXChanged( double value ); + + /** + * Emitted when the value of the right thumbstick's Y axis is changed. + * + * \see axisRightY() + */ + void axisRightYChanged( double value ); + + /** + * Emitted when the state of the A button is changed. + * + * \see buttonA() + */ + void buttonAChanged( bool value ); + + /** + * Emitted when the state of the B button is changed. + * + * \see buttonB() + */ + void buttonBChanged( bool value ); + + /** + * Emitted when the state of the X button is changed. + * + * \see buttonX() + */ + void buttonXChanged( bool value ); + + /** + * Emitted when the state of the Y button is changed. + * + * \see buttonY() + */ + void buttonYChanged( bool value ); + + /** + * Emitted when the state of the left shoulder button is changed. + * + * \see buttonL1() + */ + void buttonL1Changed( bool value ); + + /** + * Emitted when the state of the right shoulder button is changed. + * + * \see buttonR1() + */ + void buttonR1Changed( bool value ); + + /** + * Emitted when the state of the left trigger button is changed. + * + * \see buttonL2() + */ + void buttonL2Changed( double value ); + + /** + * Emitted when the state of the right trigger button is changed. + * + * \see buttonR2() + */ + void buttonR2Changed( double value ); + + /** + * Emitted when the state of the select button is changed. + * + * \see buttonSelect() + */ + void buttonSelectChanged( bool value ); + + /** + * Emitted when the state of the start button is changed. + * + * \see buttonStart() + */ + void buttonStartChanged( bool value ); + + /** + * Emitted when the state of the left stick button is changed. + * + * \see buttonL3() + */ + void buttonL3Changed( bool value ); + + /** + * Emitted when the state of the right stick button is changed. + * + * \see buttonR3() + */ + void buttonR3Changed( bool value ); + + /** + * Emitted when the state of the direction pad up button is changed. + * + * \see buttonUp() + */ + void buttonUpChanged( bool value ); + + /** + * Emitted when the state of the direction pad down button is changed. + * + * \see buttonDown() + */ + void buttonDownChanged( bool value ); + + /** + * Emitted when the state of the direction pad left button is changed. + * + * \see buttonLeft() + */ + void buttonLeftChanged( bool value ); + + /** + * Emitted when the state of the direction pad right button is changed. + * + * \see buttonRight() + */ + void buttonRightChanged( bool value ); + + /** + * Emitted when the state of the center button is changed. + * + * \see buttonCenter() + */ + void buttonCenterChanged( bool value ); + + /** + * Emitted when the state of the guide button is changed. + * + * \see buttonCenter() + */ + void buttonGuideChanged( bool value ); + + private: + + int mGamepadDeviceId = -1; + QPointer< QGamepad> mGamepad; +}; + + +#endif + +#endif // QGS3DGAMEPADCONTROLLER_H