diff --git a/images/images.qrc b/images/images.qrc
index 517d4761cb..22031a3d50 100644
--- a/images/images.qrc
+++ b/images/images.qrc
@@ -11,6 +11,7 @@
pictures/qfield-love.png
+ themes/qfield/nodpi/ic_3x3_grid_white_24dp.svg
themes/qfield/nodpi/ic_flash_auto_black_24dp.svg
themes/qfield/nodpi/ic_flash_on_black_24dp.svg
themes/qfield/nodpi/ic_flash_off_black_24dp.svg
diff --git a/images/themes/qfield/nodpi/ic_3x3_grid_white_24dp.svg b/images/themes/qfield/nodpi/ic_3x3_grid_white_24dp.svg
new file mode 100644
index 0000000000..1d09ee79a5
--- /dev/null
+++ b/images/themes/qfield/nodpi/ic_3x3_grid_white_24dp.svg
@@ -0,0 +1,4 @@
+
+
diff --git a/src/qml/imports/QFieldControls/+Qt5/QFieldCamera.qml b/src/qml/imports/QFieldControls/+Qt5/QFieldCamera.qml
index fb1cd10aff..27869b3115 100644
--- a/src/qml/imports/QFieldControls/+Qt5/QFieldCamera.qml
+++ b/src/qml/imports/QFieldControls/+Qt5/QFieldCamera.qml
@@ -1,5 +1,6 @@
import QtQuick 2.14
import QtQuick.Controls 2.14
+import QtQuick.Shapes 1.14
import QtQuick.Window 2.14
import QtMultimedia 5.14
import Qt.labs.settings 1.0
@@ -45,6 +46,7 @@ Popup {
Settings {
id: settings
property bool geoTagging: true
+ property bool showGrid: false
}
Page {
@@ -120,6 +122,7 @@ Popup {
}
VideoOutput {
+ id: videoOutput
anchors.fill: parent
visible: cameraItem.state == "PhotoCapture" || cameraItem.state == "VideoCapture"
@@ -128,6 +131,59 @@ Popup {
source: camera
autoOrientation: true
+
+ onSourceRectChanged: {
+ console.log(sourceRect)
+ }
+ }
+
+ Shape {
+ id: grid
+ visible: settings.showGrid
+ anchors.centerIn: parent
+
+ property bool isLandscape: mainWindow.width > mainWindow.height
+
+ width: isLandscape
+ ? videoOutput.sourceRect.width * mainWindow.height / videoOutput.sourceRect.height
+ : mainWindow.width
+ height: isLandscape
+ ? mainWindow.height
+ : videoOutput.sourceRect.height * mainWindow.width / videoOutput.sourceRect.width
+
+ ShapePath {
+ strokeColor: "#99000000"
+ strokeWidth: 3
+ fillColor: "transparent"
+
+ startX: grid.width / 3
+ startY: 0
+
+ PathLine { x: grid.width / 3; y: grid.height }
+ PathMove { x: grid.width / 3 * 2; y: 0 }
+ PathLine { x: grid.width / 3 * 2; y: grid.height }
+ PathMove { x: 0; y: grid.height / 3 }
+ PathLine { x: grid.width; y: grid.height / 3 }
+ PathMove { x: 0; y: grid.height / 3 * 2 }
+ PathLine { x: grid.width; y: grid.height / 3 * 2 }
+ }
+
+ ShapePath {
+ strokeColor: "#AAFFFFFF"
+ strokeWidth: 1
+ fillColor: "transparent"
+
+ startX: grid.width / 3
+ startY: 0
+
+ PathLine { x: grid.width / 3; y: grid.height }
+ PathMove { x: grid.width / 3 * 2; y: 0 }
+ PathLine { x: grid.width / 3 * 2; y: grid.height }
+ PathMove { x: 0; y: grid.height / 3 }
+ PathLine { x: grid.width; y: grid.height / 3 }
+ PathMove { x: 0; y: grid.height / 3 * 2 }
+ PathLine { x: grid.width; y: grid.height / 3 * 2 }
+ }
}
MouseArea {
@@ -209,97 +265,103 @@ Popup {
Rectangle {
x: cameraItem.isPortraitMode ? 0 : parent.width - 100
- y: cameraItem.isPortraitMode ? parent.height - 100 : 0
+ y: cameraItem.isPortraitMode ? parent.height - 100 - mainWindow.sceneBottomMargin : 0
width: cameraItem.isPortraitMode ? parent.width : 100
- height: cameraItem.isPortraitMode ? 100 : parent.height
+ height: cameraItem.isPortraitMode ? 100 + mainWindow.sceneBottomMargin : parent.height
color: Theme.darkGraySemiOpaque
Rectangle {
- id: captureRing
- anchors.centerIn: parent
- width: 64
- height: 64
- radius: 32
- color: Theme.darkGraySemiOpaque
- border.color: cameraItem.state == "VideoCapture" && camera.videoRecorder.recorderState != CameraRecorder.StoppedState
- ? "red"
- : "white"
- border.width: 2
-
- QfToolButton {
- id: captureButton
+ anchors.top: parent.top
+ width: parent.width
+ height: cameraItem.isPortraitMode ? parent.height - mainWindow.sceneBottomMargin : parent.height
+ color: "transparent"
+ Rectangle {
+ id: captureRing
anchors.centerIn: parent
- visible: camera.cameraStatus == Camera.ActiveStatus ||
- camera.cameraStatus == Camera.LoadedStatus ||
- camera.cameraStatus == Camera.StandbyStatus
-
- round: true
- roundborder: true
- iconSource: cameraItem.state == "PhotoPreview" || cameraItem.state == "VideoPreview"
- ? Theme.getThemeIcon("ic_check_white_48dp")
- : ''
- bgcolor: cameraItem.state == "PhotoPreview" || cameraItem.state == "VideoPreview"
- ? Theme.mainColor
- : cameraItem.state == "VideoCapture" ? "red" : "white"
-
- onClicked: {
- if (cameraItem.state == "PhotoCapture") {
- camera.imageCapture.captureToLocation(qgisProject.homePath+ '/DCIM/')
- currentPosition = positionSource.positionInformation
- } else if (cameraItem.state == "VideoCapture") {
- if (camera.videoRecorder.recorderState == CameraRecorder.StoppedState) {
- camera.videoRecorder.record()
- } else {
- camera.videoRecorder.stop()
- videoPreview.source = camera.videoRecorder.actualLocation
- var path = camera.videoRecorder.actualLocation.toString()
- var filePos = path.indexOf('file://')
- currentPath = filePos === 0 ? path.substring(7) : path
- cameraItem.state = "VideoPreview"
- }
- } else if (cameraItem.state == "PhotoPreview" || cameraItem.state == "VideoPreview") {
- if (cameraItem.state == "PhotoPreview") {
- if (settings.geoTagging && positionSource.active) {
- FileUtils.addImageMetadata(currentPath, currentPosition)
+ width: 64
+ height: 64
+ radius: 32
+ color: Theme.darkGraySemiOpaque
+ border.color: cameraItem.state == "VideoCapture" && camera.videoRecorder.recorderState != CameraRecorder.StoppedState
+ ? "red"
+ : "white"
+ border.width: 2
+
+ QfToolButton {
+ id: captureButton
+
+ anchors.centerIn: parent
+ visible: camera.cameraStatus == Camera.ActiveStatus ||
+ camera.cameraStatus == Camera.LoadedStatus ||
+ camera.cameraStatus == Camera.StandbyStatus
+
+ round: true
+ roundborder: true
+ iconSource: cameraItem.state == "PhotoPreview" || cameraItem.state == "VideoPreview"
+ ? Theme.getThemeIcon("ic_check_white_48dp")
+ : ''
+ bgcolor: cameraItem.state == "PhotoPreview" || cameraItem.state == "VideoPreview"
+ ? Theme.mainColor
+ : cameraItem.state == "VideoCapture" ? "red" : "white"
+
+ onClicked: {
+ if (cameraItem.state == "PhotoCapture") {
+ camera.imageCapture.captureToLocation(qgisProject.homePath+ '/DCIM/')
+ currentPosition = positionSource.positionInformation
+ } else if (cameraItem.state == "VideoCapture") {
+ if (camera.videoRecorder.recorderState == CameraRecorder.StoppedState) {
+ camera.videoRecorder.record()
+ } else {
+ camera.videoRecorder.stop()
+ videoPreview.source = camera.videoRecorder.actualLocation
+ var path = camera.videoRecorder.actualLocation.toString()
+ var filePos = path.indexOf('file://')
+ currentPath = filePos === 0 ? path.substring(7) : path
+ cameraItem.state = "VideoPreview"
+ }
+ } else if (cameraItem.state == "PhotoPreview" || cameraItem.state == "VideoPreview") {
+ if (cameraItem.state == "PhotoPreview") {
+ if (settings.geoTagging && positionSource.active) {
+ FileUtils.addImageMetadata(currentPath, currentPosition)
+ }
}
+ cameraItem.finished(currentPath)
}
- cameraItem.finished(currentPath)
}
}
}
- }
- QfToolButton {
- id: zoomButton
- visible: cameraItem.isCapturing
+ QfToolButton {
+ id: zoomButton
+ visible: cameraItem.isCapturing
- x: cameraItem.isPortraitMode ? (parent.width / 4) - (width / 2) : (parent.width - width) / 2
- y: cameraItem.isPortraitMode ? (parent.height - height) / 2 : (parent.height / 4) * 3 - (height / 2)
+ x: cameraItem.isPortraitMode ? (parent.width / 4) - (width / 2) : (parent.width - width) / 2
+ y: cameraItem.isPortraitMode ? (parent.height - height) / 2 : (parent.height / 4) * 3 - (height / 2)
- iconColor: "white"
- bgcolor: Theme.darkGraySemiOpaque
- round: true
+ iconColor: "white"
+ bgcolor: Theme.darkGraySemiOpaque
+ round: true
- text: (camera.digitalZoom * camera.opticalZoom).toFixed(1) +'X'
- font: Theme.tinyFont
+ text: (camera.digitalZoom * camera.opticalZoom).toFixed(1) +'X'
+ font: Theme.tinyFont
- onClicked: {
- camera.opticalZoom = 1;
- camera.digitalZoom = 1;
+ onClicked: {
+ camera.opticalZoom = 1;
+ camera.digitalZoom = 1;
+ }
}
- }
- QfToolButton {
- id: flashButton
- visible: cameraItem.isCapturing && camera.flash.supportedModes.length > 1
+ QfToolButton {
+ id: flashButton
+ visible: cameraItem.isCapturing && camera.flash.supportedModes.length > 1
- x: cameraItem.isPortraitMode ? (parent.width / 4) * 3 - (width / 2) : (parent.width - width) / 2
- y: cameraItem.isPortraitMode ? (parent.height - height) / 2 : (parent.height / 4) - (height / 2)
+ x: cameraItem.isPortraitMode ? (parent.width / 4) * 3 - (width / 2) : (parent.width - width) / 2
+ y: cameraItem.isPortraitMode ? (parent.height - height) / 2 : (parent.height / 4) - (height / 2)
- iconSource: {
- switch(camera.flash.mode) {
+ iconSource: {
+ switch(camera.flash.mode) {
case Camera.FlashAuto:
return Theme.getThemeVectorIcon('ic_flash_auto_black_24dp');
case Camera.FlashOn:
@@ -308,56 +370,58 @@ Popup {
return Theme.getThemeVectorIcon('ic_flash_off_black_24dp');
default:
return'';
+ }
}
- }
- iconColor: "white"
- bgcolor: Qt.hsla(Theme.darkGray.hslHue, Theme.darkGray.hslSaturation, Theme.darkGray.hslLightness, 0.5)
- round: true
+ iconColor: "white"
+ bgcolor: Qt.hsla(Theme.darkGray.hslHue, Theme.darkGray.hslSaturation, Theme.darkGray.hslLightness, 0.5)
+ round: true
- onClicked: {
- if (camera.flash.mode == Camera.FlashOff) {
- camera.flash.mode = Camera.FlashOn;
- } else {
- camera.flash.mode = Camera.FlashOff
+ onClicked: {
+ if (camera.flash.mode == Camera.FlashOff) {
+ camera.flash.mode = Camera.FlashOn;
+ } else {
+ camera.flash.mode = Camera.FlashOff
+ }
}
}
- }
-
- Rectangle {
- visible: cameraItem.state == "VideoCapture" && camera.videoRecorder.recorderState != CameraRecorder.StoppedState
-
- x: cameraItem.isPortraitMode ? captureRing.x + captureRing.width / 2 - width / 2 : captureRing.x + captureRing.width / 2 - width / 2
- y: cameraItem.isPortraitMode ? captureRing.y - height - 20 : captureRing.y - height - 20
-
- width: durationLabelMetrics.boundingRect('00:00:00').width + 20
- height: durationLabelMetrics.boundingRect('00:00:00').height + 10
- radius: 6
- color: 'red'
-
- Text {
- id: durationLabel
- anchors.centerIn: parent
- text: {
- if (camera.videoRecorder.duration > 0) {
- var seconds = Math.ceil(camera.videoRecorder.duration / 1000);
- var hours = Math.floor(seconds / 60 / 60) + '';
- seconds -= hours * 60 * 60;
- var minutes = Math.floor(seconds / 60) + '';
- seconds = (seconds - minutes * 60) + '';
- return hours.padStart(2,'0') + ':' + minutes.padStart(2,'0') + ':' + seconds.padStart(2,'0');
- } else {
- // tiny bit of a cheat here as the first second isn't triggered
- return '00:00:01';
+ Rectangle {
+ visible: cameraItem.state == "VideoCapture" && camera.videoRecorder.recorderState != CameraRecorder.StoppedState
+
+ x: cameraItem.isPortraitMode ? captureRing.x + captureRing.width / 2 - width / 2 : captureRing.x + captureRing.width / 2 - width / 2
+ y: cameraItem.isPortraitMode ? captureRing.y - height - 20 : captureRing.y - height - 20
+
+ width: durationLabelMetrics.boundingRect('00:00:00').width + 20
+ height: durationLabelMetrics.boundingRect('00:00:00').height + 10
+ radius: 6
+
+ color: 'red'
+
+ Text {
+ id: durationLabel
+ anchors.centerIn: parent
+ text: {
+ if (camera.videoRecorder.duration > 0) {
+ var seconds = Math.ceil(camera.videoRecorder.duration / 1000);
+ var hours = Math.floor(seconds / 60 / 60) + '';
+ seconds -= hours * 60 * 60;
+ var minutes = Math.floor(seconds / 60) + '';
+ seconds = (seconds - minutes * 60) + '';
+ return hours.padStart(2,'0') + ':' + minutes.padStart(2,'0') + ':' + seconds.padStart(2,'0');
+ } else {
+ // tiny bit of a cheat here as the first second isn't triggered
+ return '00:00:01';
+ }
}
+ color: 'white'
}
- color: 'white'
- }
- FontMetrics {
- id: durationLabelMetrics
- font: durationLabel.font
+ FontMetrics {
+ id: durationLabelMetrics
+ font: durationLabel.font
+ }
}
+
}
}
@@ -407,5 +471,24 @@ Popup {
}
}
}
+
+ QfToolButton {
+ id: gridButton
+
+ anchors.left: parent.left
+ anchors.leftMargin: 4
+ anchors.top: geotagButton.bottom
+ anchors.topMargin: 4
+
+ iconSource: Theme.getThemeVectorIcon("ic_3x3_grid_white_24dp")
+ iconColor: settings.showGrid ? Theme.mainColor : "white"
+ bgcolor: Theme.darkGraySemiOpaque
+ round: true
+
+ onClicked: {
+ settings.showGrid = !settings.showGrid
+ displayToast(settings.showGrid ? qsTr("Grid enabled") : qsTr("Grid disabled"))
+ }
+ }
}
}
diff --git a/src/qml/imports/QFieldControls/+Qt6/QFieldCamera.qml b/src/qml/imports/QFieldControls/+Qt6/QFieldCamera.qml
index f0534fcb4f..17b1e50da6 100644
--- a/src/qml/imports/QFieldControls/+Qt6/QFieldCamera.qml
+++ b/src/qml/imports/QFieldControls/+Qt6/QFieldCamera.qml
@@ -1,5 +1,6 @@
import QtQuick
import QtQuick.Controls
+import QtQuick.Shapes
import QtQuick.Window
import QtMultimedia
import Qt.labs.settings
@@ -43,6 +44,7 @@ Popup {
Settings {
id: settings
property bool geoTagging: true
+ property bool showGrid: false
}
Page {
@@ -107,6 +109,55 @@ Popup {
visible: cameraItem.state == "PhotoCapture" || cameraItem.state == "VideoCapture"
}
+ Shape {
+ id: grid
+ visible: settings.showGrid
+ anchors.centerIn: parent
+
+ property bool isLandscape: mainWindow.width > mainWindow.height
+
+ width: isLandscape
+ ? videoOutput.sourceRect.width * mainWindow.height / videoOutput.sourceRect.height
+ : mainWindow.width
+ height: isLandscape
+ ? mainWindow.height
+ : videoOutput.sourceRect.height * mainWindow.width / videoOutput.sourceRect.width
+
+ ShapePath {
+ strokeColor: "#99000000"
+ strokeWidth: 3
+ fillColor: "transparent"
+
+ startX: grid.width / 3
+ startY: 0
+
+ PathLine { x: grid.width / 3; y: grid.height }
+ PathMove { x: grid.width / 3 * 2; y: 0 }
+ PathLine { x: grid.width / 3 * 2; y: grid.height }
+ PathMove { x: 0; y: grid.height / 3 }
+ PathLine { x: grid.width; y: grid.height / 3 }
+ PathMove { x: 0; y: grid.height / 3 * 2 }
+ PathLine { x: grid.width; y: grid.height / 3 * 2 }
+ }
+
+ ShapePath {
+ strokeColor: "#AAFFFFFF"
+ strokeWidth: 1
+ fillColor: "transparent"
+
+ startX: grid.width / 3
+ startY: 0
+
+ PathLine { x: grid.width / 3; y: grid.height }
+ PathMove { x: grid.width / 3 * 2; y: 0 }
+ PathLine { x: grid.width / 3 * 2; y: grid.height }
+ PathMove { x: 0; y: grid.height / 3 }
+ PathLine { x: grid.width; y: grid.height / 3 }
+ PathMove { x: 0; y: grid.height / 3 * 2 }
+ PathLine { x: grid.width; y: grid.height / 3 * 2 }
+ }
+ }
+
PinchHandler {
enabled: cameraItem.visible && cameraItem.isCapturing
target: null
@@ -180,146 +231,162 @@ Popup {
color: Theme.darkGraySemiOpaque
Rectangle {
- id: captureRing
- anchors.centerIn: parent
- width: 64
- height: 64
- radius: 32
+ x: cameraItem.isPortraitMode ? 0 : parent.width - 100
+ y: cameraItem.isPortraitMode ? parent.height - 100 - mainWindow.sceneBottomMargin : 0
+ width: cameraItem.isPortraitMode ? parent.width : 100
+ height: cameraItem.isPortraitMode ? 100 + mainWindow.sceneBottomMargin : parent.height
+
color: Theme.darkGraySemiOpaque
- border.color: cameraItem.state == "VideoCapture" && captureSession.recorder.recorderState !== MediaRecorder.StoppedState
- ? "red"
- : "white"
- border.width: 2
-
- QfToolButton {
- id: captureButton
-
- anchors.centerIn: parent
- visible: camera.cameraStatus == Camera.ActiveStatus ||
- camera.cameraStatus == Camera.LoadedStatus ||
- camera.cameraStatus == Camera.StandbyStatus
-
- round: true
- roundborder: true
- iconSource: cameraItem.state == "PhotoPreview" || cameraItem.state == "VideoPreview"
- ? Theme.getThemeIcon("ic_check_white_48dp")
- : ''
- bgcolor: cameraItem.state == "PhotoPreview" || cameraItem.state == "VideoPreview"
- ? Theme.mainColor
- : cameraItem.state == "VideoCapture" ? "red" : "white"
-
- onClicked: {
- if (cameraItem.state == "PhotoCapture") {
- captureSession.imageCapture.captureToFile(qgisProject.homePath+ '/DCIM/')
- currentPosition = positionSource.positionInformation
- } else if (cameraItem.state == "VideoCapture") {
- if (captureSession.recorder.recorderState === MediaRecorder.StoppedState) {
- captureSession.recorder.record()
- } else {
- captureSession.recorder.stop()
- videoPreview.source = captureSession.recorder.actualLocation
- var path = captureSession.recorder.actualLocation.toString()
- var filePos = path.indexOf('file://')
- currentPath = filePos === 0 ? path.substring(7) : path
- cameraItem.state = "VideoPreview"
- }
- } else if (cameraItem.state == "PhotoPreview" || cameraItem.state == "VideoPreview") {
- if (cameraItem.state == "PhotoPreview") {
- if (settings.geoTagging && positionSource.active) {
- FileUtils.addImageMetadata(currentPath, currentPosition)
+
+ Rectangle {
+ anchors.top: parent.top
+ width: parent.width
+ height: cameraItem.isPortraitMode ? parent.height - mainWindow.sceneBottomMargin : parent.height
+ color: "transparent"
+
+ Rectangle {
+ id: captureRing
+ anchors.centerIn: parent
+ width: 64
+ height: 64
+ radius: 32
+ color: Theme.darkGraySemiOpaque
+ border.color: cameraItem.state == "VideoCapture" && captureSession.recorder.recorderState !== MediaRecorder.StoppedState
+ ? "red"
+ : "white"
+ border.width: 2
+
+ QfToolButton {
+ id: captureButton
+
+ anchors.centerIn: parent
+ visible: camera.cameraStatus == Camera.ActiveStatus ||
+ camera.cameraStatus == Camera.LoadedStatus ||
+ camera.cameraStatus == Camera.StandbyStatus
+
+ round: true
+ roundborder: true
+ iconSource: cameraItem.state == "PhotoPreview" || cameraItem.state == "VideoPreview"
+ ? Theme.getThemeIcon("ic_check_white_48dp")
+ : ''
+ bgcolor: cameraItem.state == "PhotoPreview" || cameraItem.state == "VideoPreview"
+ ? Theme.mainColor
+ : cameraItem.state == "VideoCapture" ? "red" : "white"
+
+ onClicked: {
+ if (cameraItem.state == "PhotoCapture") {
+ captureSession.imageCapture.captureToFile(qgisProject.homePath+ '/DCIM/')
+ currentPosition = positionSource.positionInformation
+ } else if (cameraItem.state == "VideoCapture") {
+ if (captureSession.recorder.recorderState === MediaRecorder.StoppedState) {
+ captureSession.recorder.record()
+ } else {
+ captureSession.recorder.stop()
+ videoPreview.source = captureSession.recorder.actualLocation
+ var path = captureSession.recorder.actualLocation.toString()
+ var filePos = path.indexOf('file://')
+ currentPath = filePos === 0 ? path.substring(7) : path
+ cameraItem.state = "VideoPreview"
+ }
+ } else if (cameraItem.state == "PhotoPreview" || cameraItem.state == "VideoPreview") {
+ if (cameraItem.state == "PhotoPreview") {
+ if (settings.geoTagging && positionSource.active) {
+ FileUtils.addImageMetadata(currentPath, currentPosition)
+ }
+ }
+ cameraItem.finished(currentPath)
}
}
- cameraItem.finished(currentPath)
}
}
- }
- }
- QfToolButton {
- id: zoomButton
- visible: cameraItem.isCapturing
+ QfToolButton {
+ id: zoomButton
+ visible: cameraItem.isCapturing
- x: cameraItem.isPortraitMode ? (parent.width / 4) - (width / 2) : (parent.width - width) / 2
- y: cameraItem.isPortraitMode ? (parent.height - height) / 2 : (parent.height / 4) * 3 - (height / 2)
+ x: cameraItem.isPortraitMode ? (parent.width / 4) - (width / 2) : (parent.width - width) / 2
+ y: cameraItem.isPortraitMode ? (parent.height - height) / 2 : (parent.height / 4) * 3 - (height / 2)
- iconColor: "white"
- bgcolor: Theme.darkGraySemiOpaque
- round: true
+ iconColor: "white"
+ bgcolor: Theme.darkGraySemiOpaque
+ round: true
- text: camera.zoomFactor.toFixed(1) +'X'
- font: Theme.tinyFont
+ text: camera.zoomFactor.toFixed(1) +'X'
+ font: Theme.tinyFont
- onClicked: {
- camera.zoomFactor = 1;
- }
- }
-
- QfToolButton {
- id: flashButton
- visible: cameraItem.isCapturing && camera.isFlashModeSupported(Camera.FlashOn)
-
- x: cameraItem.isPortraitMode ? (parent.width / 4) * 3 - (width / 2) : (parent.width - width) / 2
- y: cameraItem.isPortraitMode ? (parent.height - height) / 2 : (parent.height / 4) - (height / 2)
-
- iconSource: {
- switch(camera.flashMode) {
- case Camera.FlashAuto:
- return Theme.getThemeVectorIcon('ic_flash_auto_black_24dp');
- case Camera.FlashOn:
- return Theme.getThemeVectorIcon('ic_flash_on_black_24dp');
- case Camera.FlashOff:
- return Theme.getThemeVectorIcon('ic_flash_off_black_24dp');
- default:
- return'';
+ onClicked: {
+ camera.zoomFactor = 1;
+ }
}
- }
- iconColor: "white"
- bgcolor: Qt.hsla(Theme.darkGray.hslHue, Theme.darkGray.hslSaturation, Theme.darkGray.hslLightness, 0.5)
- round: true
- onClicked: {
- if (camera.flashMode === Camera.FlashOff) {
- camera.flashMode = Camera.FlashOn;
- } else {
- camera.flashMode = Camera.FlashOff
- }
- }
- }
+ QfToolButton {
+ id: flashButton
+ visible: cameraItem.isCapturing && camera.isFlashModeSupported(Camera.FlashOn)
+
+ x: cameraItem.isPortraitMode ? (parent.width / 4) * 3 - (width / 2) : (parent.width - width) / 2
+ y: cameraItem.isPortraitMode ? (parent.height - height) / 2 : (parent.height / 4) - (height / 2)
+
+ iconSource: {
+ switch(camera.flashMode) {
+ case Camera.FlashAuto:
+ return Theme.getThemeVectorIcon('ic_flash_auto_black_24dp');
+ case Camera.FlashOn:
+ return Theme.getThemeVectorIcon('ic_flash_on_black_24dp');
+ case Camera.FlashOff:
+ return Theme.getThemeVectorIcon('ic_flash_off_black_24dp');
+ default:
+ return'';
+ }
+ }
+ iconColor: "white"
+ bgcolor: Qt.hsla(Theme.darkGray.hslHue, Theme.darkGray.hslSaturation, Theme.darkGray.hslLightness, 0.5)
+ round: true
- Rectangle {
- visible: cameraItem.state == "VideoCapture" && captureSession.recorder.recorderState !== MediaRecorder.StoppedState
-
- x: cameraItem.isPortraitMode ? captureRing.x + captureRing.width / 2 - width / 2 : captureRing.x + captureRing.width / 2 - width / 2
- y: cameraItem.isPortraitMode ? captureRing.y - height - 20 : captureRing.y - height - 20
-
- width: durationLabelMetrics.boundingRect('00:00:00').width + 20
- height: durationLabelMetrics.boundingRect('00:00:00').height + 10
- radius: 6
-
- color: 'red'
-
- Text {
- id: durationLabel
- anchors.centerIn: parent
- text: {
- if (captureSession.recorder.duration > 0) {
- var seconds = Math.ceil(captureSession.recorder.duration / 1000);
- var hours = Math.floor(seconds / 60 / 60) + '';
- seconds -= hours * 60 * 60;
- var minutes = Math.floor(seconds / 60) + '';
- seconds = (seconds - minutes * 60) + '';
- return hours.padStart(2,'0') + ':' + minutes.padStart(2,'0') + ':' + seconds.padStart(2,'0');
- } else {
- // tiny bit of a cheat here as the first second isn't triggered
- return '00:00:01';
+ onClicked: {
+ if (camera.flashMode === Camera.FlashOff) {
+ camera.flashMode = Camera.FlashOn;
+ } else {
+ camera.flashMode = Camera.FlashOff
+ }
}
}
- color: 'white'
- }
- FontMetrics {
- id: durationLabelMetrics
- font: durationLabel.font
+ Rectangle {
+ visible: cameraItem.state == "VideoCapture" && captureSession.recorder.recorderState !== MediaRecorder.StoppedState
+
+ x: cameraItem.isPortraitMode ? captureRing.x + captureRing.width / 2 - width / 2 : captureRing.x + captureRing.width / 2 - width / 2
+ y: cameraItem.isPortraitMode ? captureRing.y - height - 20 : captureRing.y - height - 20
+
+ width: durationLabelMetrics.boundingRect('00:00:00').width + 20
+ height: durationLabelMetrics.boundingRect('00:00:00').height + 10
+ radius: 6
+
+ color: 'red'
+
+ Text {
+ id: durationLabel
+ anchors.centerIn: parent
+ text: {
+ if (captureSession.recorder.duration > 0) {
+ var seconds = Math.ceil(captureSession.recorder.duration / 1000);
+ var hours = Math.floor(seconds / 60 / 60) + '';
+ seconds -= hours * 60 * 60;
+ var minutes = Math.floor(seconds / 60) + '';
+ seconds = (seconds - minutes * 60) + '';
+ return hours.padStart(2,'0') + ':' + minutes.padStart(2,'0') + ':' + seconds.padStart(2,'0');
+ } else {
+ // tiny bit of a cheat here as the first second isn't triggered
+ return '00:00:01';
+ }
+ }
+ color: 'white'
+ }
+
+ FontMetrics {
+ id: durationLabelMetrics
+ font: durationLabel.font
+ }
+ }
}
}
}
@@ -370,5 +437,24 @@ Popup {
}
}
}
+
+ QfToolButton {
+ id: gridButton
+
+ anchors.left: parent.left
+ anchors.leftMargin: 4
+ anchors.top: geotagButton.bottom
+ anchors.topMargin: 4
+
+ iconSource: Theme.getThemeVectorIcon("ic_3x3_grid_white_24dp")
+ iconColor: settings.showGrid ? Theme.mainColor : "white"
+ bgcolor: Theme.darkGraySemiOpaque
+ round: true
+
+ onClicked: {
+ settings.showGrid = !settings.showGrid
+ displayToast(settings.showGrid ? qsTr("Grid enabled") : qsTr("Grid disabled"))
+ }
+ }
}
}