diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index c557bbefa6309f1c183598bb1afdbf48dfe7f928..622c93738c7e0e151a17bb719cc9b9beb998963e 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -66,6 +66,8 @@ src/QmlControls/AppMessages.qml src/QmlControls/AxisMonitor.qml src/PlanView/CameraCalc.qml + src/PlanView/CameraCalcCamera.qml + src/PlanView/CameraCalcGrid.qml src/PlanView/CameraSection.qml src/QmlControls/ClickableColor.qml src/PlanView/CorridorScanMapVisual.qml diff --git a/src/PlanView/CameraCalcCamera.qml b/src/PlanView/CameraCalcCamera.qml new file mode 100644 index 0000000000000000000000000000000000000000..d18eef7803f40863c59b4bfc004728089361213e --- /dev/null +++ b/src/PlanView/CameraCalcCamera.qml @@ -0,0 +1,183 @@ +import QtQuick 2.3 +import QtQuick.Controls 1.2 +import QtQuick.Layouts 1.2 + +import QGroundControl 1.0 +import QGroundControl.ScreenTools 1.0 +import QGroundControl.Controls 1.0 +import QGroundControl.FactControls 1.0 +import QGroundControl.Palette 1.0 + +// Camera calculator "Camera" section for mission item editors +Column { + anchors.left: parent.left + anchors.right: parent.right + spacing: _margin + + visible: !usingPreset || !cameraSpecifiedInPreset + + property var cameraCalc + property bool vehicleFlightIsFrontal: true + property string distanceToSurfaceLabel + property int distanceToSurfaceAltitudeMode: QGroundControl.AltitudeModeNone + property string frontalDistanceLabel + property string sideDistanceLabel + property bool usingPreset: false + property bool cameraSpecifiedInPreset: false + + property real _margin: ScreenTools.defaultFontPixelWidth / 2 + property string _cameraName: cameraCalc.cameraName.value + property real _fieldWidth: ScreenTools.defaultFontPixelWidth * 10.5 + property var _cameraList: [ ] + property var _vehicle: QGroundControl.multiVehicleManager.activeVehicle ? QGroundControl.multiVehicleManager.activeVehicle : QGroundControl.multiVehicleManager.offlineEditingVehicle + property var _vehicleCameraList: _vehicle ? _vehicle.staticCameraList : [] + property bool _cameraComboFilled: false + + readonly property int _gridTypeManual: 0 + readonly property int _gridTypeCustomCamera: 1 + readonly property int _gridTypeCamera: 2 + + Component.onCompleted: _fillCameraCombo() + + on_CameraNameChanged: _updateSelectedCamera() + + function _fillCameraCombo() { + _cameraComboFilled = true + _cameraList.push(cameraCalc.manualCameraName) + _cameraList.push(cameraCalc.customCameraName) + for (var i=0; i<_vehicle.staticCameraList.length; i++) { + _cameraList.push(_vehicle.staticCameraList[i].name) + } + gridTypeCombo.model = _cameraList + _updateSelectedCamera() + } + + function _updateSelectedCamera() { + if (_cameraComboFilled) { + var knownCameraIndex = gridTypeCombo.find(_cameraName) + if (knownCameraIndex !== -1) { + gridTypeCombo.currentIndex = knownCameraIndex + } else { + console.log("Internal error: Known camera not found", _cameraName) + gridTypeCombo.currentIndex = _gridTypeCustomCamera + } + } + } + + QGCPalette { id: qgcPal; colorGroupEnabled: true } + + ExclusiveGroup { + id: cameraOrientationGroup + } + + Column { + anchors.left: parent.left + anchors.right: parent.right + spacing: _margin + + QGCComboBox { + id: gridTypeCombo + anchors.left: parent.left + anchors.right: parent.right + model: _cameraList + currentIndex: -1 + onActivated: cameraCalc.cameraName.value = gridTypeCombo.textAt(index) + } // QGCComboxBox + + // Camera based grid ui + Column { + anchors.left: parent.left + anchors.right: parent.right + spacing: _margin + visible: !cameraCalc.isManualCamera + + Row { + spacing: _margin + anchors.horizontalCenter: parent.horizontalCenter + visible: !cameraCalc.fixedOrientation.value + + QGCRadioButton { + width: _editFieldWidth + text: "Landscape" + checked: !!cameraCalc.landscape.value + onClicked: cameraCalc.landscape.value = 1 + } + + QGCRadioButton { + id: cameraOrientationPortrait + text: "Portrait" + checked: !cameraCalc.landscape.value + onClicked: cameraCalc.landscape.value = 0 + } + } + + // Custom camera specs + Column { + id: custCameraCol + anchors.left: parent.left + anchors.right: parent.right + spacing: _margin + visible: cameraCalc.isCustomCamera + + RowLayout { + anchors.left: parent.left + anchors.right: parent.right + spacing: _margin + Item { Layout.fillWidth: true } + QGCLabel { + Layout.preferredWidth: _root._fieldWidth + text: qsTr("Width") + } + QGCLabel { + Layout.preferredWidth: _root._fieldWidth + text: qsTr("Height") + } + } + + RowLayout { + anchors.left: parent.left + anchors.right: parent.right + spacing: _margin + QGCLabel { text: qsTr("Sensor"); Layout.fillWidth: true } + FactTextField { + Layout.preferredWidth: _root._fieldWidth + fact: cameraCalc.sensorWidth + } + FactTextField { + Layout.preferredWidth: _root._fieldWidth + fact: cameraCalc.sensorHeight + } + } + + RowLayout { + anchors.left: parent.left + anchors.right: parent.right + spacing: _margin + QGCLabel { text: qsTr("Image"); Layout.fillWidth: true } + FactTextField { + Layout.preferredWidth: _root._fieldWidth + fact: cameraCalc.imageWidth + } + FactTextField { + Layout.preferredWidth: _root._fieldWidth + fact: cameraCalc.imageHeight + } + } + + RowLayout { + anchors.left: parent.left + anchors.right: parent.right + spacing: _margin + QGCLabel { + text: qsTr("Focal length") + Layout.fillWidth: true + } + FactTextField { + Layout.preferredWidth: _root._fieldWidth + fact: cameraCalc.focalLength + } + } + } // Column - custom camera specs + } // Column - Camera spec based ui + } // Column - Camera Section +} // Column diff --git a/src/PlanView/CameraCalcGrid.qml b/src/PlanView/CameraCalcGrid.qml new file mode 100644 index 0000000000000000000000000000000000000000..65fb7de7abb2ff4d884c52ddee32904f9fddb38b --- /dev/null +++ b/src/PlanView/CameraCalcGrid.qml @@ -0,0 +1,153 @@ +import QtQuick 2.3 +import QtQuick.Controls 1.2 +import QtQuick.Layouts 1.2 + +import QGroundControl 1.0 +import QGroundControl.ScreenTools 1.0 +import QGroundControl.Controls 1.0 +import QGroundControl.FactControls 1.0 +import QGroundControl.Palette 1.0 + +// Camera calculator "Grid" section for mission item editors +Column { + anchors.left: parent.left + anchors.right: parent.right + spacing: _margin + + visible: !usingPreset || !cameraSpecifiedInPreset + + property var cameraCalc + property bool vehicleFlightIsFrontal: true + property string distanceToSurfaceLabel + property int distanceToSurfaceAltitudeMode: QGroundControl.AltitudeModeNone + property string frontalDistanceLabel + property string sideDistanceLabel + property bool usingPreset: false + property bool cameraSpecifiedInPreset: false + + property real _margin: ScreenTools.defaultFontPixelWidth / 2 + property string _cameraName: cameraCalc.cameraName.value + property real _fieldWidth: ScreenTools.defaultFontPixelWidth * 10.5 + property var _cameraList: [ ] + property var _vehicle: QGroundControl.multiVehicleManager.activeVehicle ? QGroundControl.multiVehicleManager.activeVehicle : QGroundControl.multiVehicleManager.offlineEditingVehicle + property var _vehicleCameraList: _vehicle ? _vehicle.staticCameraList : [] + property bool _cameraComboFilled: false + + readonly property int _gridTypeManual: 0 + readonly property int _gridTypeCustomCamera: 1 + readonly property int _gridTypeCamera: 2 + + QGCPalette { id: qgcPal; colorGroupEnabled: true } + + Column { + anchors.left: parent.left + anchors.right: parent.right + spacing: _margin + visible: !cameraCalc.isManualCamera + + RowLayout { + anchors.left: parent.left + anchors.right: parent.right + spacing: _margin + visible: !usingPreset + Item { Layout.fillWidth: true } + QGCLabel { + Layout.preferredWidth: _root._fieldWidth + text: qsTr("Front Lap") + } + QGCLabel { + Layout.preferredWidth: _root._fieldWidth + text: qsTr("Side Lap") + } + } + + RowLayout { + anchors.left: parent.left + anchors.right: parent.right + spacing: _margin + visible: !usingPreset + QGCLabel { text: qsTr("Overlap"); Layout.fillWidth: true } + FactTextField { + Layout.preferredWidth: _root._fieldWidth + fact: cameraCalc.frontalOverlap + } + FactTextField { + Layout.preferredWidth: _root._fieldWidth + fact: cameraCalc.sideOverlap + } + } + + QGCLabel { + wrapMode: Text.WordWrap + text: qsTr("Select one:") + Layout.preferredWidth: parent.width + Layout.columnSpan: 2 + visible: !usingPreset + } + + GridLayout { + anchors.left: parent.left + anchors.right: parent.right + columnSpacing: _margin + rowSpacing: _margin + columns: 2 + visible: !usingPreset + + QGCRadioButton { + id: fixedDistanceRadio + text: distanceToSurfaceLabel + checked: !!cameraCalc.valueSetIsDistance.value + onClicked: cameraCalc.valueSetIsDistance.value = 1 + } + + AltitudeFactTextField { + fact: cameraCalc.distanceToSurface + altitudeMode: distanceToSurfaceAltitudeMode + enabled: fixedDistanceRadio.checked + Layout.fillWidth: true + } + + QGCRadioButton { + id: fixedImageDensityRadio + text: qsTr("Ground Res") + checked: !cameraCalc.valueSetIsDistance.value + onClicked: cameraCalc.valueSetIsDistance.value = 0 + } + + FactTextField { + fact: cameraCalc.imageDensity + enabled: fixedImageDensityRadio.checked + Layout.fillWidth: true + } + } + } // Column - Camera spec based ui + + // No camera spec ui + GridLayout { + anchors.left: parent.left + anchors.right: parent.right + columnSpacing: _margin + rowSpacing: _margin + columns: 2 + visible: cameraCalc.isManualCamera + + QGCLabel { text: distanceToSurfaceLabel } + AltitudeFactTextField { + fact: cameraCalc.distanceToSurface + altitudeMode: distanceToSurfaceAltitudeMode + Layout.fillWidth: true + } + + QGCLabel { text: frontalDistanceLabel } + FactTextField { + Layout.fillWidth: true + fact: cameraCalc.adjustedFootprintFrontal + } + + QGCLabel { text: sideDistanceLabel } + FactTextField { + Layout.fillWidth: true + fact: cameraCalc.adjustedFootprintSide + } + } // GridLayout +} // Column diff --git a/src/PlanView/CorridorScanEditor.qml b/src/PlanView/CorridorScanEditor.qml index bc82745fca5af38b2b6fa006b0dad1a2a9a2acb3..a1447716d6eee56b362d8725d6cd4f3179b03971 100644 --- a/src/PlanView/CorridorScanEditor.qml +++ b/src/PlanView/CorridorScanEditor.qml @@ -56,136 +56,172 @@ Rectangle { anchors.right: parent.right spacing: _margin - QGCLabel { + QGCTabBar { + id: tabBar anchors.left: parent.left anchors.right: parent.right - text: qsTr("WARNING: Photo interval is below minimum interval (%1 secs) supported by camera.").arg(_cameraMinTriggerInterval.toFixed(1)) - wrapMode: Text.WordWrap - color: qgcPal.warningText - visible: missionItem.cameraShots > 0 && _cameraMinTriggerInterval !== 0 && _cameraMinTriggerInterval > missionItem.timeBetweenShots - } + Component.onCompleted: currentIndex = 0 - CameraCalc { - cameraCalc: missionItem.cameraCalc - vehicleFlightIsFrontal: true - distanceToSurfaceLabel: qsTr("Altitude") - distanceToSurfaceAltitudeMode: missionItem.followTerrain ? - QGroundControl.AltitudeModeAboveTerrain : - missionItem.cameraCalc.distanceToSurfaceRelative - frontalDistanceLabel: qsTr("Trigger Dist") - sideDistanceLabel: qsTr("Spacing") + QGCTabButton { text: qsTr("Grid") } + QGCTabButton { text: qsTr("Camera") } } - SectionHeader { - id: corridorHeader - text: qsTr("Corridor") - } + Column { + anchors.left: parent.left + anchors.right: parent.right + spacing: _margin + visible: tabBar.currentIndex == 0 + + QGCLabel { + anchors.left: parent.left + anchors.right: parent.right + text: qsTr("WARNING: Photo interval is below minimum interval (%1 secs) supported by camera.").arg(_cameraMinTriggerInterval.toFixed(1)) + wrapMode: Text.WordWrap + color: qgcPal.warningText + visible: missionItem.cameraShots > 0 && _cameraMinTriggerInterval !== 0 && _cameraMinTriggerInterval > missionItem.timeBetweenShots + } - GridLayout { - anchors.left: parent.left - anchors.right: parent.right - columnSpacing: _margin - rowSpacing: _margin - columns: 2 - visible: corridorHeader.checked - - QGCLabel { text: qsTr("Width") } - FactTextField { - fact: missionItem.corridorWidth - Layout.fillWidth: true + + CameraCalcGrid { + cameraCalc: missionItem.cameraCalc + vehicleFlightIsFrontal: true + distanceToSurfaceLabel: qsTr("Altitude") + distanceToSurfaceAltitudeMode: missionItem.followTerrain ? + QGroundControl.AltitudeModeAboveTerrain : + missionItem.cameraCalc.distanceToSurfaceRelative + frontalDistanceLabel: qsTr("Trigger Dist") + sideDistanceLabel: qsTr("Spacing") } - QGCLabel { text: qsTr("Turnaround dist") } - FactTextField { - fact: missionItem.turnAroundDistance - Layout.fillWidth: true + SectionHeader { + id: corridorHeader + text: qsTr("Corridor") } - QGCOptionsComboBox { - Layout.columnSpan: 2 - Layout.fillWidth: true - - model: [ - { - text: qsTr("Images in turnarounds"), - fact: missionItem.cameraTriggerInTurnAround, - enabled: missionItem.hoverAndCaptureAllowed ? !missionItem.hoverAndCapture.rawValue : true, - visible: true - }, - { - text: qsTr("Relative altitude"), - enabled: missionItem.cameraCalc.isManualCamera && !missionItem.followTerrain, - visible: QGroundControl.corePlugin.options.showMissionAbsoluteAltitude || (!missionItem.cameraCalc.distanceToSurfaceRelative && !missionItem.followTerrain), - checked: missionItem.cameraCalc.distanceToSurfaceRelative - } - ] + GridLayout { + anchors.left: parent.left + anchors.right: parent.right + columnSpacing: _margin + rowSpacing: _margin + columns: 2 + visible: corridorHeader.checked + + QGCLabel { text: qsTr("Width") } + FactTextField { + fact: missionItem.corridorWidth + Layout.fillWidth: true + } - onItemClicked: { - if (index == 1) { - missionItem.cameraCalc.distanceToSurfaceRelative = !missionItem.cameraCalc.distanceToSurfaceRelative - console.log(missionItem.cameraCalc.distanceToSurfaceRelative) - } + QGCLabel { text: qsTr("Turnaround dist") } + FactTextField { + fact: missionItem.turnAroundDistance + Layout.fillWidth: true } - } - } - QGCButton { - text: qsTr("Rotate Entry Point") - onClicked: missionItem.rotateEntryPoint() - } + QGCOptionsComboBox { + Layout.columnSpan: 2 + Layout.fillWidth: true - SectionHeader { - id: terrainHeader - text: qsTr("Terrain") - checked: missionItem.followTerrain - } + model: [ + { + text: qsTr("Images in turnarounds"), + fact: missionItem.cameraTriggerInTurnAround, + enabled: missionItem.hoverAndCaptureAllowed ? !missionItem.hoverAndCapture.rawValue : true, + visible: true + }, + { + text: qsTr("Relative altitude"), + enabled: missionItem.cameraCalc.isManualCamera && !missionItem.followTerrain, + visible: QGroundControl.corePlugin.options.showMissionAbsoluteAltitude || (!missionItem.cameraCalc.distanceToSurfaceRelative && !missionItem.followTerrain), + checked: missionItem.cameraCalc.distanceToSurfaceRelative + } + ] + + onItemClicked: { + if (index == 1) { + missionItem.cameraCalc.distanceToSurfaceRelative = !missionItem.cameraCalc.distanceToSurfaceRelative + console.log(missionItem.cameraCalc.distanceToSurfaceRelative) + } + } + } + } - ColumnLayout { - anchors.left: parent.left - anchors.right: parent.right - spacing: _margin - visible: terrainHeader.checked + QGCButton { + text: qsTr("Rotate Entry Point") + onClicked: missionItem.rotateEntryPoint() + } - QGCCheckBox { - id: followsTerrainCheckBox - text: qsTr("Vehicle follows terrain") + SectionHeader { + id: terrainHeader + text: qsTr("Terrain") checked: missionItem.followTerrain - onClicked: missionItem.followTerrain = checked } - GridLayout { - Layout.fillWidth: true - columnSpacing: _margin - rowSpacing: _margin - columns: 2 - visible: followsTerrainCheckBox.checked - - QGCLabel { text: qsTr("Tolerance") } - FactTextField { - fact: missionItem.terrainAdjustTolerance - Layout.fillWidth: true + ColumnLayout { + anchors.left: parent.left + anchors.right: parent.right + spacing: _margin + visible: terrainHeader.checked + + QGCCheckBox { + id: followsTerrainCheckBox + text: qsTr("Vehicle follows terrain") + checked: missionItem.followTerrain + onClicked: missionItem.followTerrain = checked } - QGCLabel { text: qsTr("Max Climb Rate") } - FactTextField { - fact: missionItem.terrainAdjustMaxClimbRate + GridLayout { Layout.fillWidth: true - } + columnSpacing: _margin + rowSpacing: _margin + columns: 2 + visible: followsTerrainCheckBox.checked + + QGCLabel { text: qsTr("Tolerance") } + FactTextField { + fact: missionItem.terrainAdjustTolerance + Layout.fillWidth: true + } - QGCLabel { text: qsTr("Max Descent Rate") } - FactTextField { - fact: missionItem.terrainAdjustMaxDescentRate - Layout.fillWidth: true + QGCLabel { text: qsTr("Max Climb Rate") } + FactTextField { + fact: missionItem.terrainAdjustMaxClimbRate + Layout.fillWidth: true + } + + QGCLabel { text: qsTr("Max Descent Rate") } + FactTextField { + fact: missionItem.terrainAdjustMaxDescentRate + Layout.fillWidth: true + } } } - } - SectionHeader { - id: statsHeader - text: qsTr("Statistics") - } + SectionHeader { + id: statsHeader + text: qsTr("Statistics") + } - TransectStyleComplexItemStats { } - } // Column + TransectStyleComplexItemStats { } + } // Grid Column + + Column { + anchors.left: parent.left + anchors.right: parent.right + spacing: _margin + visible: tabBar.currentIndex == 1 + + CameraCalcCamera { + cameraCalc: missionItem.cameraCalc + vehicleFlightIsFrontal: true + distanceToSurfaceLabel: qsTr("Altitude") + distanceToSurfaceAltitudeMode: missionItem.followTerrain ? + QGroundControl.AltitudeModeAboveTerrain : + missionItem.cameraCalc.distanceToSurfaceRelative + frontalDistanceLabel: qsTr("Trigger Dist") + sideDistanceLabel: qsTr("Spacing") + } + } // Camera Column + } } // Rectangle diff --git a/src/PlanView/StructureScanEditor.qml b/src/PlanView/StructureScanEditor.qml index ea8d4542d5b820da7c7a590323d36ec3ce0fb320..03fb156509465805f5b6a3e11273a39e96d647ce 100644 --- a/src/PlanView/StructureScanEditor.qml +++ b/src/PlanView/StructureScanEditor.qml @@ -57,132 +57,166 @@ Rectangle { anchors.right: parent.right spacing: _margin - QGCLabel { + QGCTabBar { + id: tabBar anchors.left: parent.left anchors.right: parent.right - text: qsTr("Note: Polygon respresents structure surface not vehicle flight path.") - wrapMode: Text.WordWrap - font.pointSize: ScreenTools.smallFontPointSize - } - - QGCLabel { - anchors.left: parent.left - anchors.right: parent.right - text: qsTr("WARNING: Photo interval is below minimum interval (%1 secs) supported by camera.").arg(_cameraMinTriggerInterval.toFixed(1)) - wrapMode: Text.WordWrap - color: qgcPal.warningText - visible: missionItem.cameraShots > 0 && _cameraMinTriggerInterval !== 0 && _cameraMinTriggerInterval > missionItem.timeBetweenShots - } - CameraCalc { - cameraCalc: missionItem.cameraCalc - vehicleFlightIsFrontal: false - distanceToSurfaceLabel: qsTr("Scan Distance") - distanceToSurfaceAltitudeMode: QGroundControl.AltitudeModeNone - frontalDistanceLabel: qsTr("Layer Height") - sideDistanceLabel: qsTr("Trigger Distance") - } + Component.onCompleted: currentIndex = 0 - SectionHeader { - id: scanHeader - text: qsTr("Scan") + QGCTabButton { text: qsTr("Grid") } + QGCTabButton { text: qsTr("Camera") } } Column { - anchors.left: parent.left - anchors.right: parent.right - spacing: _margin - visible: scanHeader.checked + anchors.left: parent.left + anchors.right: parent.right + spacing: _margin + visible: tabBar.currentIndex == 0 - GridLayout { + QGCLabel { anchors.left: parent.left anchors.right: parent.right - columnSpacing: _margin - rowSpacing: _margin - columns: 2 + text: qsTr("Note: Polygon respresents structure surface not vehicle flight path.") + wrapMode: Text.WordWrap + font.pointSize: ScreenTools.smallFontPointSize + } - FactComboBox { - fact: missionItem.startFromTop - indexModel: true - model: [ qsTr("Start Scan From Bottom"), qsTr("Start Scan From Top") ] - Layout.columnSpan: 2 - Layout.fillWidth: true - } + QGCLabel { + anchors.left: parent.left + anchors.right: parent.right + text: qsTr("WARNING: Photo interval is below minimum interval (%1 secs) supported by camera.").arg(_cameraMinTriggerInterval.toFixed(1)) + wrapMode: Text.WordWrap + color: qgcPal.warningText + visible: missionItem.cameraShots > 0 && _cameraMinTriggerInterval !== 0 && _cameraMinTriggerInterval > missionItem.timeBetweenShots + } - QGCLabel { - text: qsTr("Structure Height") - } - FactTextField { - fact: missionItem.structureHeight - Layout.fillWidth: true - } + CameraCalcGrid { + cameraCalc: missionItem.cameraCalc + vehicleFlightIsFrontal: false + distanceToSurfaceLabel: qsTr("Scan Distance") + distanceToSurfaceAltitudeMode: QGroundControl.AltitudeModeNone + frontalDistanceLabel: qsTr("Layer Height") + sideDistanceLabel: qsTr("Trigger Distance") + } - QGCLabel { text: qsTr("Scan Bottom Alt") } - AltitudeFactTextField { - fact: missionItem.scanBottomAlt - altitudeMode: QGroundControl.AltitudeModeRelative - Layout.fillWidth: true - } + SectionHeader { + id: scanHeader + text: qsTr("Scan") + } - QGCLabel { text: qsTr("Entrance/Exit Alt") } - AltitudeFactTextField { - fact: missionItem.entranceAlt - altitudeMode: QGroundControl.AltitudeModeRelative - Layout.fillWidth: true + Column { + anchors.left: parent.left + anchors.right: parent.right + spacing: _margin + visible: scanHeader.checked + + GridLayout { + anchors.left: parent.left + anchors.right: parent.right + columnSpacing: _margin + rowSpacing: _margin + columns: 2 + + FactComboBox { + fact: missionItem.startFromTop + indexModel: true + model: [ qsTr("Start Scan From Bottom"), qsTr("Start Scan From Top") ] + Layout.columnSpan: 2 + Layout.fillWidth: true + } + + QGCLabel { + text: qsTr("Structure Height") + } + FactTextField { + fact: missionItem.structureHeight + Layout.fillWidth: true + } + + QGCLabel { text: qsTr("Scan Bottom Alt") } + AltitudeFactTextField { + fact: missionItem.scanBottomAlt + altitudeMode: QGroundControl.AltitudeModeRelative + Layout.fillWidth: true + } + + QGCLabel { text: qsTr("Entrance/Exit Alt") } + AltitudeFactTextField { + fact: missionItem.entranceAlt + altitudeMode: QGroundControl.AltitudeModeRelative + Layout.fillWidth: true + } + + QGCLabel { + text: qsTr("Gimbal Pitch") + visible: missionItem.cameraCalc.isManualCamera + } + FactTextField { + fact: missionItem.gimbalPitch + Layout.fillWidth: true + visible: missionItem.cameraCalc.isManualCamera + } } - QGCLabel { - text: qsTr("Gimbal Pitch") - visible: missionItem.cameraCalc.isManualCamera - } - FactTextField { - fact: missionItem.gimbalPitch - Layout.fillWidth: true - visible: missionItem.cameraCalc.isManualCamera + Item { + height: ScreenTools.defaultFontPixelHeight / 2 + width: 1 } - } - Item { - height: ScreenTools.defaultFontPixelHeight / 2 - width: 1 - } + QGCButton { + text: qsTr("Rotate entry point") + onClicked: missionItem.rotateEntryPoint() + } + } // Column - Scan - QGCButton { - text: qsTr("Rotate entry point") - onClicked: missionItem.rotateEntryPoint() + SectionHeader { + id: statsHeader + text: qsTr("Statistics") } - } // Column - Scan - SectionHeader { - id: statsHeader - text: qsTr("Statistics") - } + Grid { + columns: 2 + columnSpacing: ScreenTools.defaultFontPixelWidth + visible: statsHeader.checked - Grid { - columns: 2 - columnSpacing: ScreenTools.defaultFontPixelWidth - visible: statsHeader.checked + QGCLabel { text: qsTr("Layers") } + QGCLabel { text: missionItem.layers.valueString } - QGCLabel { text: qsTr("Layers") } - QGCLabel { text: missionItem.layers.valueString } + QGCLabel { text: qsTr("Layer Height") } + QGCLabel { text: missionItem.cameraCalc.adjustedFootprintFrontal.valueString + " " + QGroundControl.appSettingsDistanceUnitsString } - QGCLabel { text: qsTr("Layer Height") } - QGCLabel { text: missionItem.cameraCalc.adjustedFootprintFrontal.valueString + " " + QGroundControl.appSettingsDistanceUnitsString } + QGCLabel { text: qsTr("Top Layer Alt") } + QGCLabel { text: QGroundControl.metersToAppSettingsDistanceUnits(missionItem.topFlightAlt).toFixed(1) + " " + QGroundControl.appSettingsDistanceUnitsString } - QGCLabel { text: qsTr("Top Layer Alt") } - QGCLabel { text: QGroundControl.metersToAppSettingsDistanceUnits(missionItem.topFlightAlt).toFixed(1) + " " + QGroundControl.appSettingsDistanceUnitsString } + QGCLabel { text: qsTr("Bottom Layer Alt") } + QGCLabel { text: QGroundControl.metersToAppSettingsDistanceUnits(missionItem.bottomFlightAlt).toFixed(1) + " " + QGroundControl.appSettingsDistanceUnitsString } - QGCLabel { text: qsTr("Bottom Layer Alt") } - QGCLabel { text: QGroundControl.metersToAppSettingsDistanceUnits(missionItem.bottomFlightAlt).toFixed(1) + " " + QGroundControl.appSettingsDistanceUnitsString } + QGCLabel { text: qsTr("Photo Count") } + QGCLabel { text: missionItem.cameraShots } - QGCLabel { text: qsTr("Photo Count") } - QGCLabel { text: missionItem.cameraShots } + QGCLabel { text: qsTr("Photo Interval") } + QGCLabel { text: missionItem.timeBetweenShots.toFixed(1) + " " + qsTr("secs") } - QGCLabel { text: qsTr("Photo Interval") } - QGCLabel { text: missionItem.timeBetweenShots.toFixed(1) + " " + qsTr("secs") } + QGCLabel { text: qsTr("Trigger Distance") } + QGCLabel { text: missionItem.cameraCalc.adjustedFootprintSide.valueString + " " + QGroundControl.appSettingsDistanceUnitsString } + } + } // Grid Column - QGCLabel { text: qsTr("Trigger Distance") } - QGCLabel { text: missionItem.cameraCalc.adjustedFootprintSide.valueString + " " + QGroundControl.appSettingsDistanceUnitsString } - } - } // Column + Column { + anchors.left: parent.left + anchors.right: parent.right + spacing: _margin + visible: tabBar.currentIndex == 1 + + CameraCalcCamera { + cameraCalc: missionItem.cameraCalc + vehicleFlightIsFrontal: false + distanceToSurfaceLabel: qsTr("Scan Distance") + distanceToSurfaceAltitudeMode: QGroundControl.AltitudeModeNone + frontalDistanceLabel: qsTr("Layer Height") + sideDistanceLabel: qsTr("Trigger Distance") + } + } // Camera Column + } } // Rectangle diff --git a/src/PlanView/SurveyItemEditor.qml b/src/PlanView/SurveyItemEditor.qml index a5644517a177f1c526f12b5646422f319d8211cc..e4a5fc7f66e4f4c2cc6c0c82b708ba24938bf762 100644 --- a/src/PlanView/SurveyItemEditor.qml +++ b/src/PlanView/SurveyItemEditor.qml @@ -58,176 +58,103 @@ Rectangle { anchors.right: parent.right spacing: _margin - QGCLabel { + QGCTabBar { + id: tabBar anchors.left: parent.left anchors.right: parent.right - text: qsTr("WARNING: Photo interval is below minimum interval (%1 secs) supported by camera.").arg(_cameraMinTriggerInterval.toFixed(1)) - wrapMode: Text.WordWrap - color: qgcPal.warningText - visible: missionItem.cameraShots > 0 && _cameraMinTriggerInterval !== 0 && _cameraMinTriggerInterval > missionItem.timeBetweenShots - } - QGCLabel { - text: qsTr("Presets") + Component.onCompleted: currentIndex = 0 + + QGCTabButton { text: qsTr("Grid") } + QGCTabButton { text: qsTr("Camera") } + QGCTabButton { text: qsTr("Presets") } } - QGCComboBox { - id: presetCombo + Column { anchors.left: parent.left anchors.right: parent.right - model: _presetList - - property var _presetList: [] - - readonly property int _indexCustom: 0 - readonly property int _indexCreate: 1 - readonly property int _indexDelete: 2 - readonly property int _indexLabel: 3 - readonly property int _indexFirstPreset: 4 - - Component.onCompleted: _updateList() - - onActivated: { - if (index == _indexCustom) { - missionItem.clearCurrentPreset() - } else if (index == _indexCreate) { - mainWindow.showComponentDialog(savePresetDialog, qsTr("Save Preset"), mainWindow.showDialogDefaultWidth, StandardButton.Save | StandardButton.Cancel) - } else if (index == _indexDelete) { - if (missionItem.builtInPreset) { - mainWindow.showMessage(qsTr("Delete Preset"), qsTr("This preset cannot be deleted.")) - } else { - missionItem.deleteCurrentPreset() - } - } else if (index >= _indexFirstPreset) { - missionItem.loadPreset(textAt(index)) - } else { - _selectCurrentPreset() - } - } - - Connections { - target: missionItem + spacing: _margin + visible: tabBar.currentIndex == 0 - onPresetNamesChanged: presetCombo._updateList() - onCurrentPresetChanged: presetCombo._selectCurrentPreset() + QGCLabel { + anchors.left: parent.left + anchors.right: parent.right + text: qsTr("WARNING: Photo interval is below minimum interval (%1 secs) supported by camera.").arg(_cameraMinTriggerInterval.toFixed(1)) + wrapMode: Text.WordWrap + color: qgcPal.warningText + visible: missionItem.cameraShots > 0 && _cameraMinTriggerInterval !== 0 && _cameraMinTriggerInterval > missionItem.timeBetweenShots } - // There is some major strangeness going on with programatically changing the index of a combo box in this scenario. - // If you just set currentIndex directly it will just change back 1o -1 magically. Has something to do with resetting - // model on the fly I think. But not sure. To work around I delay the currentIndex changes to let things unwind. - Timer { - id: delayedIndexChangeTimer - interval: 10 - - property int newIndex - - onTriggered: presetCombo.currentIndex = newIndex - + CameraCalcGrid { + cameraCalc: missionItem.cameraCalc + vehicleFlightIsFrontal: true + distanceToSurfaceLabel: qsTr("Altitude") + distanceToSurfaceAltitudeMode: missionItem.followTerrain ? + QGroundControl.AltitudeModeAboveTerrain : + missionItem.cameraCalc.distanceToSurfaceRelative + frontalDistanceLabel: qsTr("Trigger Dist") + sideDistanceLabel: qsTr("Spacing") + usingPreset: _usingPreset + cameraSpecifiedInPreset: missionItem.cameraInPreset } - function delayedIndexChange(index) { - delayedIndexChangeTimer.newIndex = index - delayedIndexChangeTimer.start() + SectionHeader { + id: transectsHeader + text: qsTr("Transects") } - function _updateList() { - _presetList = [] - _presetList.push(qsTr("Custom (specify all settings)")) - _presetList.push(qsTr("Save Settings As Preset")) - _presetList.push(qsTr("Delete Current Preset")) - if (missionItem.presetNames.length !== 0) { - _presetList.push(qsTr("Presets:")) - } + GridLayout { + anchors.left: parent.left + anchors.right: parent.right + columnSpacing: _margin + rowSpacing: _margin + columns: 2 + visible: transectsHeader.checked - for (var i=0; i= _indexFirstPreset) { + missionItem.loadPreset(textAt(index)) + } else { + _selectCurrentPreset() + } } - } - ColumnLayout { - anchors.left: parent.left - anchors.right: parent.right - spacing: ScreenTools.defaultFontPixelHeight + Connections { + target: missionItem - QGCLabel { - Layout.fillWidth: true - text: qsTr("Save the current settings as a named preset.") - wrapMode: Text.WordWrap + onPresetNamesChanged: presetCombo._updateList() + onCurrentPresetChanged: presetCombo._selectCurrentPreset() } - QGCLabel { - text: qsTr("Preset Name") + // There is some major strangeness going on with programatically changing the index of a combo box in this scenario. + // If you just set currentIndex directly it will just change back 1o -1 magically. Has something to do with resetting + // model on the fly I think. But not sure. To work around I delay the currentIndex changes to let things unwind. + Timer { + id: delayedIndexChangeTimer + interval: 10 + + property int newIndex + + onTriggered: presetCombo.currentIndex = newIndex + } - QGCTextField { - id: presetNameField - Layout.fillWidth: true - text: _currentPreset + function delayedIndexChange(index) { + delayedIndexChangeTimer.newIndex = index + delayedIndexChangeTimer.start() } - QGCCheckBox { - text: qsTr("Save Camera In Preset") - checked: missionItem.cameraInPreset - onClicked: missionItem.cameraInPreset = checked + function _updateList() { + _presetList = [] + _presetList.push(qsTr("Custom (specify all settings)")) + _presetList.push(qsTr("Save Settings As Preset")) + _presetList.push(qsTr("Delete Current Preset")) + if (missionItem.presetNames.length !== 0) { + _presetList.push(qsTr("Presets:")) + } + + for (var i=0; i