diff --git a/images/images.qrc b/images/images.qrc
index 0cf78b2bbd..372e14d16c 100644
--- a/images/images.qrc
+++ b/images/images.qrc
@@ -286,6 +286,7 @@
themes/qfield/nodpi/ic_flashlight_green_48dp.svg
themes/qfield/nodpi/ic_gallery_black_24dp.svg
themes/qfield/nodpi/ic_microphone_black_24dp.svg
+ themes/qfield/nodpi/ic_camera_switch_black_24dp.svg
themes/qfield/nodpi/ic_camera_photo_black_24dp.svg
themes/qfield/nodpi/ic_camera_video_black_24dp.svg
themes/qfield/hdpi/ic_camera_white_36dp.png
diff --git a/images/themes/qfield/nodpi/ic_camera_switch_black_24dp.svg b/images/themes/qfield/nodpi/ic_camera_switch_black_24dp.svg
new file mode 100644
index 0000000000..8861c3e323
--- /dev/null
+++ b/images/themes/qfield/nodpi/ic_camera_switch_black_24dp.svg
@@ -0,0 +1,4 @@
+
+
diff --git a/src/qml/QFieldCamera.qml b/src/qml/QFieldCamera.qml
index 5403215773..44c24bee79 100644
--- a/src/qml/QFieldCamera.qml
+++ b/src/qml/QFieldCamera.qml
@@ -52,6 +52,21 @@ Popup {
}
}
+ Component.onCompleted: {
+ let cameraPicked = false
+ if (settings.deviceId != '') {
+ for(const device of mediaDevices.videoInputs) {
+ if (device.id == settings.deviceId) {
+ camera.cameraDevice = device
+ cameraPicked = true
+ }
+ }
+ }
+ if (!cameraPicked) {
+ camera.cameraDevice = mediaDevices.defaultVideoInput
+ }
+ }
+
QfCameraPermission {
id: cameraPermission
}
@@ -63,6 +78,7 @@ Popup {
id: settings
property bool geoTagging: true
property bool showGrid: false
+ property string deviceId: ''
}
Page {
@@ -86,7 +102,6 @@ Popup {
id: camera
active: cameraItem.visible && cameraPermission.status === Qt.PermissionStatus.Granted
- cameraDevice: mediaDevices.defaultVideoInput
function zoomIn(increase) {
var zoom = camera.zoomFactor + increase
@@ -433,11 +448,79 @@ Popup {
}
QfToolButton {
- id: geotagButton
+ id: cameraSelectionButton
anchors.left: parent.left
anchors.leftMargin: 4
anchors.top: backButton.bottom
+ anchors.topMargin: cameraSelectionMenu.count > 1 ? 4 : 0
+
+ width: 48
+ height: cameraSelectionMenu.count > 1 ? 48 : 0
+
+ iconSource: Theme.getThemeVectorIcon("ic_camera_switch_black_24dp")
+ iconColor: "white"
+ bgcolor: Theme.darkGraySemiOpaque
+ round: true
+
+ onClicked: {
+ cameraSelectionMenu.popup(cameraSelectionButton.x, cameraSelectionButton.y)
+ }
+ }
+
+ Menu {
+ id: cameraSelectionMenu
+
+ width: {
+ let result = 50;
+ let padding = 0;
+ for (let i = 0; i < count; ++i) {
+ let item = itemAt(i);
+ result = Math.max(item.contentItem.implicitWidth, result);
+ padding = Math.max(item.leftPadding + item.rightPadding, padding);
+ }
+ return mainWindow.width > 0 ? Math.min(result + padding, mainWindow.width - 20) : 0;
+ }
+
+ Repeater {
+ model: mediaDevices.videoInputs
+
+ delegate: MenuItem {
+ property string deviceId: modelData.id
+ property bool isDefault: modelData.isDefault
+
+ text: modelData.description +
+ (modelData.position !== CameraDevice.UnspecifiedPosition
+ ? ' (' + (modelData.position === CameraDevice.FrontFace
+ ? qsTr('front') : qsTr('back')) + ')'
+ : '')
+ height: 48
+ leftPadding: Theme.menuItemCheckLeftPadding
+ font: Theme.defaultFont
+ enabled: !checked
+ checkable: true
+ checked: deviceId == settings.deviceId || (isDefault && settings.deviceId == '')
+ indicator.height: 20
+ indicator.width: 20
+ indicator.implicitHeight: 24
+ indicator.implicitWidth: 24
+
+ onCheckedChanged: {
+ if (checked && settings.deviceId !== modelData.id) {
+ settings.deviceId = modelData.id
+ camera.cameraDevice = modelData
+ }
+ }
+ }
+ }
+ }
+
+ QfToolButton {
+ id: geotagButton
+
+ anchors.left: parent.left
+ anchors.leftMargin: 4
+ anchors.top: cameraSelectionButton.bottom
anchors.topMargin: 4
iconSource: positionSource.active ? Theme.getThemeIcon("ic_geotag_24dp") : Theme.getThemeIcon("ic_geotag_missing_24dp")