QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
TransectStyleComplexItemEditor.qml
Go to the documentation of this file.
1import QtQuick
2import QtQuick.Controls
3import QtQuick.Dialogs
4import QtQuick.Layouts
5
6import QGroundControl
7import QGroundControl.Controls
8import QGroundControl.FactControls
9import QGroundControl.FlightMap
10
11Rectangle {
12 id: _root
13 height: childrenRect.y + childrenRect.height + _margin
14 width: availableWidth
15 color: qgcPal.windowShadeDark
16 radius: _radius
17
18 required property var missionItem
19 required property real availableWidth
20
21 property bool transectAreaDefinitionComplete: true
22 property string transectAreaDefinitionHelp: _internalError
23 property string transectValuesHeaderName: _internalError
24 property var transectValuesComponent: undefined
25 property var presetsTransectValuesComponent: undefined
26
27 readonly property string _internalError: "Internal Error"
28
29 property var _missionItem: missionItem
30 property real _margin: ScreenTools.defaultFontPixelWidth / 2
31 property real _fieldWidth: ScreenTools.defaultFontPixelWidth * 10.5
32 property var _vehicle: QGroundControl.multiVehicleManager.activeVehicle ? QGroundControl.multiVehicleManager.activeVehicle : QGroundControl.multiVehicleManager.offlineEditingVehicle
33 property real _cameraMinTriggerInterval: _missionItem.cameraCalc.minTriggerInterval.rawValue
34 property string _doneAdjusting: qsTr("Done")
35 property bool _presetsAvailable: _missionItem.presetNames.length !== 0
36
37 function polygonCaptureStarted() {
38 _missionItem.clearPolygon()
39 }
40
41 function polygonCaptureFinished(coordinates) {
42 for (var i=0; i<coordinates.length; i++) {
43 _missionItem.addPolygonCoordinate(coordinates[i])
44 }
45 }
46
47 function polygonAdjustVertex(vertexIndex, vertexCoordinate) {
48 _missionItem.adjustPolygonCoordinate(vertexIndex, vertexCoordinate)
49 }
50
51 function polygonAdjustStarted() { }
52 function polygonAdjustFinished() { }
53
54 QGCPalette { id: qgcPal; colorGroupEnabled: true }
55
56 ColumnLayout {
57 id: editorColumn
58 anchors.margins: _margin
59 anchors.top: parent.top
60 anchors.left: parent.left
61 anchors.right: parent.right
62
63 QGCLabel {
64 id: transectAreaDefinitionCompleteLabel
65 Layout.fillWidth: true
66 wrapMode: Text.WordWrap
67 horizontalAlignment: Text.AlignHCenter
68 text: transectAreaDefinitionHelp
69 visible: !transectAreaDefinitionComplete || _missionItem.wizardMode
70 }
71
72 ColumnLayout {
73 Layout.fillWidth: true
74 spacing: _margin
75 visible: transectAreaDefinitionComplete && !_missionItem.wizardMode
76
77 TransectStyleComplexItemTabBar {
78 id: tabBar
79 Layout.fillWidth: true
80 }
81
82 // Grid tab
83 ColumnLayout {
84 Layout.fillWidth: true
85 spacing: _margin
86 visible: tabBar.currentIndex === 0
87
88 QGCLabel {
89 Layout.fillWidth: true
90 text: qsTr("WARNING: Photo interval is below minimum interval (%1 secs) supported by camera.").arg(_cameraMinTriggerInterval.toFixed(1))
91 wrapMode: Text.WordWrap
92 color: qgcPal.warningText
93 visible: _missionItem.cameraShots > 0 && _cameraMinTriggerInterval !== 0 && _cameraMinTriggerInterval > _missionItem.timeBetweenShots
94 }
95
96 CameraCalcGrid {
97 Layout.fillWidth: true
98 cameraCalc: _missionItem.cameraCalc
99 vehicleFlightIsFrontal: true
100 distanceToSurfaceLabel: qsTr("Altitude")
101 frontalDistanceLabel: qsTr("Trigger Dist")
102 sideDistanceLabel: qsTr("Spacing")
103 }
104
105 SectionHeader {
106 id: transectValuesHeader
107 Layout.fillWidth: true
108 text: transectValuesHeaderName
109 }
110
111 Loader {
112 Layout.fillWidth: true
113 visible: transectValuesHeader.checked
114 sourceComponent: transectValuesComponent
115
116 property bool forPresets: false
117 }
118
119 QGCButton {
120 Layout.alignment: Qt.AlignHCenter
121 text: qsTr("Rotate Entry Point")
122 onClicked: _missionItem.rotateEntryPoint()
123 visible: transectValuesHeader.checked
124 }
125
126 SectionHeader {
127 id: statsHeader
128 Layout.fillWidth: true
129 text: qsTr("Statistics")
130 }
131
132 TransectStyleComplexItemStats {
133 Layout.fillWidth: true
134 visible: statsHeader.checked
135 }
136 } // Grid Column
137
138 // Camera Tab
139 CameraCalcCamera {
140 Layout.fillWidth: true
141 visible: tabBar.currentIndex === 1
142 cameraCalc: _missionItem.cameraCalc
143 }
144
145 // Terrain Tab
146 TransectStyleComplexItemTerrainFollow {
147 Layout.fillWidth: true
148 spacing: _margin
149 visible: tabBar.currentIndex === 2
150 missionItem: _missionItem
151 }
152
153 // Presets Tab
154 ColumnLayout {
155 Layout.fillWidth: true
156 spacing: _margin
157 visible: tabBar.currentIndex === 3
158
159 QGCLabel {
160 Layout.fillWidth: true
161 text: qsTr("Presets")
162 wrapMode: Text.WordWrap
163 }
164
165 QGCComboBox {
166 id: presetCombo
167 Layout.fillWidth: true
168 model: _missionItem.presetNames
169 }
170
171 RowLayout {
172 Layout.fillWidth: true
173
174 QGCButton {
175 Layout.fillWidth: true
176 text: qsTr("Apply Preset")
177 enabled: _missionItem.presetNames.length != 0
178 onClicked: _missionItem.loadPreset(presetCombo.textAt(presetCombo.currentIndex))
179 }
180
181 QGCButton {
182 Layout.fillWidth: true
183 text: qsTr("Delete Preset")
184 enabled: _missionItem.presetNames.length != 0
185 onClicked: deletePresetDialogFactory.open({ presetName: presetCombo.textAt(presetCombo.currentIndex) })
186
187 QGCPopupDialogFactory {
188 id: deletePresetDialogFactory
189
190 dialogComponent: deletePresetDialog
191 }
192
193 Component {
194 id: deletePresetDialog
195
196 QGCSimpleMessageDialog {
197 title: qsTr("Delete Preset")
198 text: qsTr("Are you sure you want to delete '%1' preset?").arg(presetName)
199 buttons: Dialog.Yes | Dialog.No
200
201 property string presetName
202
203 onAccepted: { _missionItem.deletePreset(presetName) }
204 }
205 }
206 }
207 }
208
209 Item { height: ScreenTools.defaultFontPixelHeight; width: 1 }
210
211 QGCButton {
212 Layout.alignment: Qt.AlignCenter
213 Layout.fillWidth: true
214 text: qsTr("Save Settings As New Preset")
215 onClicked: savePresetDialogFactory.open()
216 }
217
218 SectionHeader {
219 id: presectsTransectValuesHeader
220 Layout.fillWidth: true
221 text: transectValuesHeaderName
222 visible: !!presetsTransectValuesComponent
223 }
224
225 Loader {
226 Layout.fillWidth: true
227 visible: presectsTransectValuesHeader.checked && !!presetsTransectValuesComponent
228 sourceComponent: presetsTransectValuesComponent
229
230 property bool forPresets: true
231 }
232
233 SectionHeader {
234 id: presetsStatsHeader
235 Layout.fillWidth: true
236 text: qsTr("Statistics")
237 }
238
239 TransectStyleComplexItemStats {
240 Layout.fillWidth: true
241 visible: presetsStatsHeader.checked
242 }
243 } // Main editing column
244 } // Top level Column
245
246 QGCPopupDialogFactory {
247 id: savePresetDialogFactory
248
249 dialogComponent: savePresetDialog
250 }
251
252 Component {
253 id: savePresetDialog
254
255 QGCPopupDialog {
256 id: popupDialog
257 title: qsTr("Save Preset")
258 buttons: Dialog.Save | Dialog.Cancel
259
260 onAccepted: {
261 if (presetNameField.text != "") {
262 _missionItem.savePreset(presetNameField.text.trim())
263 } else {
264 preventClose = true
265 }
266 }
267
268 ColumnLayout {
269 width: ScreenTools.defaultFontPixelWidth * 30
270 spacing: ScreenTools.defaultFontPixelHeight
271
272 QGCLabel {
273 Layout.fillWidth: true
274 text: qsTr("Save the current settings as a named preset.")
275 wrapMode: Text.WordWrap
276 }
277
278 QGCLabel {
279 text: qsTr("Preset Name")
280 }
281
282 QGCTextField {
283 id: presetNameField
284 Layout.fillWidth: true
285 placeholderText: qsTr("Enter preset name")
286
287 Component.onCompleted: validateText(presetNameField.text)
288 onTextChanged: validateText(text)
289
290 function validateText(text) {
291 if (text.trim() === "") {
292 nameError.text = qsTr("Preset name cannot be blank.")
293 popupDialog.acceptButtonEnabled = false
294 } else if (text.includes("/")) {
295 nameError.text = qsTr("Preset name cannot include the \"/\" character.")
296 popupDialog.acceptButtonEnabled = false
297 } else {
298 nameError.text = ""
299 popupDialog.acceptButtonEnabled = true
300 }
301 }
302 }
303
304 QGCLabel {
305 id: nameError
306 Layout.fillWidth: true
307 wrapMode: Text.WordWrap
308 color: QGroundControl.globalPalette.warningText
309 visible: text !== ""
310 }
311 }
312 }
313 }
314 }
315}