diff --git a/custom-example/custom.qrc b/custom-example/custom.qrc
index 87a6f17..c27db1e 100644
--- a/custom-example/custom.qrc
+++ b/custom-example/custom.qrc
@@ -45,4 +45,8 @@
res/Custom/Widgets/CustomVehicleButton.qml
res/Custom/Widgets/qmldir
+
+ res/Custom/Camera/qmldir
+ res/Custom/Camera/ZoomControl.qml
+
diff --git a/custom-example/deploy/qgroundcontrol-start.sh b/custom-example/deploy/qgroundcontrol-start.sh
new file mode 100755
index 0000000..76c2f52
--- /dev/null
+++ b/custom-example/deploy/qgroundcontrol-start.sh
@@ -0,0 +1,10 @@
+#!/bin/sh
+HERE="$(dirname "$(readlink -f "${0}")")"
+export LD_LIBRARY_PATH="${HERE}/usr/lib/x86_64-linux-gnu":"${HERE}/Qt/libs":$LD_LIBRARY_PATH
+export QML2_IMPORT_PATH="${HERE}/Qt/qml"
+export QT_PLUGIN_PATH="${HERE}/Qt/plugins"
+
+# hack until icon issue with AppImage is resolved
+mkdir -p ~/.icons && \cp -f ${HERE}/qgroundcontrol.png ~/.icons
+
+"${HERE}/CustomQGC" "$@"
diff --git a/custom-example/res/Custom/Camera/ZoomControl.qml b/custom-example/res/Custom/Camera/ZoomControl.qml
new file mode 100644
index 0000000..20e2215
--- /dev/null
+++ b/custom-example/res/Custom/Camera/ZoomControl.qml
@@ -0,0 +1,213 @@
+import QtQuick 2.0
+import QtQuick.Controls 2.4
+import QtGraphicalEffects 1.0
+
+
+Item {
+ id: _root
+
+ property color mainColor: "#000000"
+ property color contentColor: "#FFFFFF"
+ property alias fontPointSize: zoomStatusTextItem.font.pointSize
+ property real zoomLevel: NaN
+ property alias zoomLevelVisible: zoomStatusItem.visible
+ property bool showZoomPrecision: true
+
+ signal zoomIn()
+ signal zoomOut()
+ signal continuousZoomStart(var zoomIn)
+ signal continuousZoomStop()
+
+ height: zoomStatusTextItem.height * 2
+ width: (zoomLevelVisible ? (zoomStatusItem.width - zoomInButton.width/2) : 0) + zoomInButton.width + zoomOutButton.width
+
+ Rectangle {
+ id: zoomStatusItem
+
+ color: mainColor
+ opacity: 0.5
+ radius: height/2
+
+ anchors.left: _root.left
+ anchors.verticalCenter: _root.verticalCenter
+
+ width: height * 2
+ height: _root.height * 0.8
+ }
+
+ Item {
+ visible: zoomStatusItem.visible
+
+ anchors.left: zoomStatusItem.left
+ anchors.top: zoomStatusItem.top
+ anchors.right: zoomStatusItem.horizontalCenter
+ anchors.bottom: zoomStatusItem.bottom
+
+ z: zoomStatusItem.z + 1
+
+ Text {
+ id: zoomStatusTextItem
+
+ anchors.centerIn: parent
+ opacity: 2
+
+ color: _root.contentColor
+
+ text: isNaN(zoomLevel) ? "-" : "x" + _root.zoomLevel.toFixed(_root.showZoomPrecision ? 1 : 0)
+ }
+ }
+
+ Button {
+ id: zoomInButton
+ flat: true
+
+ anchors.left: zoomLevelVisible ? zoomStatusItem.horizontalCenter : _root.left
+ anchors.top: _root.top
+ width: height
+ height: _root.height
+
+ property bool holding: false
+
+ onPressed: {
+ _root.zoomIn()
+ }
+
+ onPressAndHold: {
+ holding = true
+ }
+
+ onReleased: {
+ holding = false
+ }
+
+ background: Rectangle {
+ anchors.fill: zoomInButton
+ radius: zoomInButton.width/2
+
+ color: _root.mainColor
+ }
+
+ contentItem: Item {
+ anchors.fill: zoomInButton
+ Rectangle {
+ id: zoomInMinusRectangle
+ anchors.centerIn: parent
+
+ width: zoomInButton.width * 0.4
+ height: zoomInButton.height * 0.05
+
+ color: _root.contentColor
+ }
+ Rectangle {
+ anchors.centerIn: parent
+
+ width: zoomInMinusRectangle.height
+ height: zoomInMinusRectangle.width
+
+ color: _root.contentColor
+ }
+ }
+ }
+
+ Item {
+ id: buttonSeparator
+
+ anchors.left: zoomInButton.right
+ anchors.verticalCenter: zoomInButton.verticalCenter
+ width: zoomInButton.width * 0.05
+ height: zoomInButton.height * 0.8
+
+ Rectangle {
+ radius: width * 0.2
+ anchors.centerIn: parent
+
+ width: zoomInButton.width * 0.01
+ height: parent.height * 0.8
+
+ color: _root.contentColor
+ }
+ }
+
+ Button {
+ id: zoomOutButton
+ flat: true
+
+ anchors.left: buttonSeparator.right
+ anchors.top: zoomInButton.top
+ width: height
+ height: zoomInButton.height
+
+ property bool holding: false
+
+ onPressed: {
+ _root.zoomOut()
+ }
+
+ onPressAndHold: {
+ holding = true
+ }
+
+ onReleased: {
+ holding = false
+ }
+
+ background: Rectangle {
+ anchors.fill: zoomOutButton
+ radius: zoomOutButton.width/2
+
+ color: _root.mainColor
+ }
+
+ contentItem: Item {
+ anchors.fill: zoomOutButton
+ Rectangle {
+ id: zoomOutMinusRectangle
+ anchors.centerIn: parent
+
+ width: zoomInMinusRectangle.width
+ height: zoomInMinusRectangle.height
+
+ color: _root.contentColor
+ }
+ }
+ }
+
+ // Zoom buttons background
+ Rectangle {
+ color: _root.mainColor
+ z: -1
+
+ anchors.left: zoomInButton.horizontalCenter
+ anchors.right: zoomOutButton.horizontalCenter
+ anchors.top: zoomInButton.top
+ anchors.bottom: zoomOutButton.bottom
+ }
+
+ onStateChanged: {
+ if(state == "ZoomingIn") {
+ _root.continuousZoomStart(true)
+ }
+ else if(state == "ZoomingOut") {
+ _root.continuousZoomStart(false)
+ }
+ else {
+ _root.continuousZoomStop()
+ }
+ }
+
+ state: "None"
+ states: [
+ State {
+ name: "None"
+ when: zoomInButton.holding === false && zoomOutButton.holding === false
+ },
+ State {
+ name: "ZoomingIn"
+ when: zoomInButton.holding === true
+ },
+ State {
+ name: "ZoomingOut"
+ when: zoomOutButton.holding === true
+ }
+ ]
+}
diff --git a/custom-example/res/Custom/Camera/qmldir b/custom-example/res/Custom/Camera/qmldir
new file mode 100644
index 0000000..73c6e6c
--- /dev/null
+++ b/custom-example/res/Custom/Camera/qmldir
@@ -0,0 +1,3 @@
+module Custom.Camera
+
+ZoomControl 1.0 ZoomControl.qml
diff --git a/custom-example/res/CustomCameraControl.qml b/custom-example/res/CustomCameraControl.qml
index aa767e9..9a41878 100644
--- a/custom-example/res/CustomCameraControl.qml
+++ b/custom-example/res/CustomCameraControl.qml
@@ -28,6 +28,7 @@ import QGroundControl.Vehicle 1.0
import CustomQuickInterface 1.0
import Custom.Widgets 1.0
+import Custom.Camera 1.0
Item {
height: mainColumn.height
@@ -416,6 +417,29 @@ Item {
}
}
}
+ //-- Zoom Buttons
+ ZoomControl {
+ id: zoomControl
+ visible: _hasZoom
+ mainColor: qgcPal.window
+ contentColor: qgcPal.text
+ fontPointSize: ScreenTools.defaultFontPointSize * 1.25
+ zoomLevelVisible: false
+ zoomLevel: _hasZoom ? _camera.zoomLevel : NaN
+ anchors.horizontalCenter: parent.horizontalCenter
+ onZoomIn: {
+ _camera.stepZoom(1)
+ }
+ onZoomOut: {
+ _camera.stepZoom(-1)
+ }
+ onContinuousZoomStart: {
+ _camera.startZoom(zoomIn ? 1 : -1)
+ }
+ onContinuousZoomStop: {
+ _camera.stopZoom()
+ }
+ }
}
//-------------------------------------------------------------------------
//-- Camera Settings
diff --git a/custom-example/src/CustomPlugin.cc b/custom-example/src/CustomPlugin.cc
index 748cdbd..ed83326 100644
--- a/custom-example/src/CustomPlugin.cc
+++ b/custom-example/src/CustomPlugin.cc
@@ -205,6 +205,7 @@ CustomPlugin::createRootWindow(QObject *parent)
QQmlApplicationEngine* pEngine = new QQmlApplicationEngine(parent);
pEngine->addImportPath("qrc:/qml");
pEngine->addImportPath("qrc:/Custom/Widgets");
+ pEngine->addImportPath("qrc:/Custom/Camera");
pEngine->rootContext()->setContextProperty("joystickManager", qgcApp()->toolbox()->joystickManager());
pEngine->rootContext()->setContextProperty("debugMessageModel", AppMessages::getModel());
pEngine->load(QUrl(QStringLiteral("qrc:/qml/MainRootWindow.qml")));
diff --git a/src/Camera/QGCCameraControl.cc b/src/Camera/QGCCameraControl.cc
index 74920d2..4ad8b74 100644
--- a/src/Camera/QGCCameraControl.cc
+++ b/src/Camera/QGCCameraControl.cc
@@ -626,7 +626,7 @@ QGCCameraControl::startZoom(int direction)
_vehicle->sendMavCommand(
_compID, // Target component
MAV_CMD_SET_CAMERA_ZOOM, // Command id
- true, // ShowError
+ false, // ShowError
ZOOM_TYPE_CONTINUOUS, // Zoom type
direction); // Direction (-1 wide, 1 tele)
}
@@ -641,7 +641,7 @@ QGCCameraControl::stopZoom()
_vehicle->sendMavCommand(
_compID, // Target component
MAV_CMD_SET_CAMERA_ZOOM, // Command id
- true, // ShowError
+ false, // ShowError
ZOOM_TYPE_CONTINUOUS, // Zoom type
0); // Direction (-1 wide, 1 tele)
}