diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc
index 0869aea..0907af4 100644
--- a/qgroundcontrol.qrc
+++ b/qgroundcontrol.qrc
@@ -215,6 +215,7 @@
src/FlightDisplay/FlyViewToolStrip.qml
src/FlightDisplay/FlyViewToolStripActionList.qml
src/FlightDisplay/FlyViewVideo.qml
+ src/FlightDisplay/OnScreenGimbalController.qml
src/FlightDisplay/FlyViewWidgetLayer.qml
src/FlightDisplay/GuidedActionActionList.qml
src/FlightDisplay/GuidedActionConfirm.qml
diff --git a/src/FlightDisplay/OnScreenGimbalController.qml b/src/FlightDisplay/OnScreenGimbalController.qml
new file mode 100644
index 0000000..255dd30
--- /dev/null
+++ b/src/FlightDisplay/OnScreenGimbalController.qml
@@ -0,0 +1,101 @@
+/****************************************************************************
+ *
+ * (c) 2009-2024 QGROUNDCONTROL PROJECT
+ *
+ * QGroundControl is licensed according to the terms in the file
+ * COPYING.md in the root of the source code directory.
+ *
+ ****************************************************************************/
+
+import QtQuick 2.12
+
+import QGroundControl 1.0
+import QGroundControl.Controls 1.0
+import QGroundControl.Controllers 1.0
+import QGroundControl.ScreenTools 1.0
+import QGroundControl.Palette 1.0
+
+Item {
+ id: rootItem
+ anchors.fill: parent
+
+ property var screenX
+ property var screenY
+ property var screenXrateInitCoocked
+ property var screenYrateInitCoocked
+
+ property var activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
+ property var gimbalController: activeVehicle ? activeVehicle.gimbalController : undefined
+ property var activeGimbal: gimbalController ? gimbalController.activeGimbal : undefined
+ property bool gimbalAvailable: activeGimbal != undefined
+ property var gimbalControllerSettings: QGroundControl.settingsManager.gimbalControllerSettings
+ property bool shouldProcessClicks: gimbalControllerSettings.EnableOnScreenControl.value && activeGimbal ? true : false
+
+ function clickControl() {
+ if (!shouldProcessClicks) {
+ return
+ }
+ // If click and slide control, return, it uses press and release
+ if (!gimbalControllerSettings.ControlType.rawValue == 0) {
+ return
+ }
+ clickAndPoint(x, y)
+ }
+
+ // Sends a +-(0-1) xy value to vehicle.gimbalController.gimbalOnScreenControl
+ function clickAndPoint() {
+ if (rootItem.gimbalAvailable) {
+ var xCoocked = ( (screenX / parent.width) * 2) - 1
+ var yCoocked = -( (screenY / parent.height) * 2) + 1
+ // console.log("X global: " + x + " Y global: " + y)
+ // console.log("X coocked: " + xCoocked + " Y coocked: " + yCoocked)
+ gimbalController.gimbalOnScreenControl(xCoocked, yCoocked, true, false, false)
+ } else {
+ // We should never be here
+ console.log("gimbal not available")
+ }
+ }
+
+ function pressControl() {
+ if (!shouldProcessClicks) {
+ return
+ }
+ // If click and point control return, that is handled exclusively on clickAndPoint()
+ if (!gimbalControllerSettings.ControlType.rawValue == 1) {
+ return
+ }
+ sendRateTimer.start()
+ screenXrateInitCoocked = ( ( screenX / parent.width) * 2) - 1
+ screenYrateInitCoocked = -( ( screenY / parent.height) * 2) + 1
+ }
+
+ function releaseControl() {
+ if (!shouldProcessClicks) {
+ return
+ }
+ // If click and point control return, that is handled exclusively on clickAndPoint()
+ if (!gimbalControllerSettings.ControlType.rawValue == 1) {
+ return
+ }
+ sendRateTimer.stop()
+ screenXrateInitCoocked = null
+ screenYrateInitCoocked = null
+ }
+
+ Timer {
+ id: sendRateTimer
+ interval: 100
+ repeat: true
+ onTriggered: {
+ if (rootItem.gimbalAvailable) {
+ var xCoocked = ( ( screenX / parent.width) * 2) - 1
+ var yCoocked = -( ( screenY / parent.height) * 2) + 1
+ xCoocked -= screenXrateInitCoocked
+ yCoocked -= screenYrateInitCoocked
+ gimbalController.gimbalOnScreenControl(xCoocked, yCoocked, false, true, true)
+ } else {
+ console.log("gimbal not available")
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/src/QmlControls/QGroundControl/FlightDisplay/qmldir b/src/QmlControls/QGroundControl/FlightDisplay/qmldir
index f27005c..439df39 100644
--- a/src/QmlControls/QGroundControl/FlightDisplay/qmldir
+++ b/src/QmlControls/QGroundControl/FlightDisplay/qmldir
@@ -38,3 +38,4 @@ ObstacleDistanceOverlay 1.0 ObstacleDistanceOverlay.qml
ObstacleDistanceOverlayMap 1.0 ObstacleDistanceOverlayMap.qml
ObstacleDistanceOverlayVideo 1.0 ObstacleDistanceOverlayVideo.qml
GripperMenu 1.0 GripperMenu.qml
+OnScreenGimbalController 1.0 OnScreenGimbalController.qml