QGroundControl
Ground Control Station for MAVLink Drones
Loading...
Searching...
No Matches
InstrumentValueEditDialog.qml
Go to the documentation of this file.
1import QtQuick
2import QtQuick.Dialogs
3import QtQuick.Layouts
4import QtQuick.Controls
5
6import QGroundControl
7import QGroundControl.Controls
8import QGroundControl.FactControls
9
10QGCPopupDialog {
11 id: root
12 title: qsTr("Telemetry Display")
13 buttons: Dialog.Close
14
15 property var instrumentValueData
16
17 QGCPalette { id: qgcPal; colorGroupEnabled: parent.enabled }
18 QGCPalette { id: qgcPalDisable; colorGroupEnabled: false }
19
20 Loader {
21 sourceComponent: instrumentValueData.fact ? editorComponent : noFactComponent
22 }
23
24 Component {
25 id: noFactComponent
26
27 QGCLabel {
28 text: qsTr("Valuec requires a connected vehicle for setup.")
29 }
30 }
31
32 Component {
33 id: editorComponent
34
35 RowLayout {
36 spacing: ScreenTools.defaultFontPixelWidth
37
38 ColumnLayout {
39 spacing: ScreenTools.defaultFontPixelHeight / 2
40
41 SettingsGroupLayout {
42 heading: qsTr("Telemetry")
43
44 LabelledComboBox {
45 id: factGroupCombo
46 label: qsTr("Group")
47 model: instrumentValueData.factGroupNames
48 currentIndex: instrumentValueData.factGroupNames.indexOf(instrumentValueData.factGroupName)
49 onActivated: (index) => {
50 instrumentValueData.setFact(currentText, "")
51 instrumentValueData.icon = ""
52 instrumentValueData.text = instrumentValueData.fact.shortDescription
53 }
54 Connections {
55 target: instrumentValueData
56 onFactGroupNameChanged: factGroupCombo.currentIndex = factGroupCombo.comboBox.find(instrumentValueData.factGroupName)
57 }
58 }
59
60 LabelledComboBox {
61 id: factNamesCombo
62 label: qsTr("Value")
63 model: instrumentValueData.factValueNames
64 currentIndex: instrumentValueData.factValueNames.indexOf(instrumentValueData.factName)
65 onActivated: (index) => {
66 instrumentValueData.setFact(instrumentValueData.factGroupName, currentText)
67 instrumentValueData.icon = ""
68 instrumentValueData.text = instrumentValueData.fact.shortDescription
69 }
70 Connections {
71 target: instrumentValueData
72 onFactNameChanged: factNamesCombo.currentIndex = factNamesCombo.comboBox.find(instrumentValueData.factName)
73 }
74 }
75 }
76
77 SettingsGroupLayout {
78 heading: qsTr("Label")
79
80 ColumnLayout {
81 Layout.fillWidth: true
82 spacing: ScreenTools.defaultFontPixelHeight / 2
83
84 RowLayout {
85 Layout.fillWidth: true
86
87 QGCRadioButton {
88 id: iconRadio
89 text: qsTr("Icon")
90 Layout.fillWidth: true
91 Component.onCompleted: checked = instrumentValueData.icon != ""
92 onClicked: {
93 instrumentValueData.text = ""
94 instrumentValueData.icon = instrumentValueData.factValueGrid.iconNames[0]
95 }
96 ButtonGroup.group: labelTypeGroup
97 ButtonGroup { id: labelTypeGroup }
98 }
99
100 RowLayout {
101 id: iconOptionInputs
102 Rectangle {
103 width: height
104 height: changeIconBtn.height
105 color: qgcPal.windowShade
106 opacity: iconRadio.checked ? 1 : .3
107
108 QGCColoredImage {
109 id: valueIcon
110 anchors.centerIn: parent
111 height: ScreenTools.defaultFontPixelHeight
112 width: height
113 source: "/InstrumentValueIcons/" + (instrumentValueData.icon ? instrumentValueData.icon : instrumentValueData.factValueGrid.iconNames[0])
114 sourceSize.height: height
115 fillMode: Image.PreserveAspectFit
116 mipmap: true
117 smooth: true
118 color: valueIcon.status === Image.Error ? "red" : qgcPal.text
119 }
120 }
121 QGCButton {
122 id: changeIconBtn
123 text: qsTr("Change")
124 enabled: iconRadio.checked
125 onClicked: {
126 var updateFunction = function(icon){ instrumentValueData.icon = icon }
127 iconPickerDialogFactory.open({ iconNames: instrumentValueData.factValueGrid.iconNames, icon: instrumentValueData.icon, updateIconFunction: updateFunction })
128 }
129 }
130 }
131 }
132
133 RowLayout {
134 Layout.fillWidth: true
135
136 QGCRadioButton {
137 id: textRadio
138 text: qsTr("Text")
139 Layout.fillWidth: true
140 ButtonGroup.group: labelTypeGroup
141 Component.onCompleted: checked = instrumentValueData.icon == ""
142 onClicked: {
143 instrumentValueData.icon = ""
144 instrumentValueData.text = instrumentValueData.fact ? instrumentValueData.fact.shortDescription : qsTr("Label")
145 }
146 }
147
148 QGCTextField {
149 enabled: textRadio.checked
150 Layout.minimumWidth: iconOptionInputs.width
151 text: textRadio.checked
152 ? instrumentValueData.text
153 : instrumentValueData.fact ? instrumentValueData.fact.shortDescription : qsTr("Label")
154 onEditingFinished: instrumentValueData.text = text
155 }
156 }
157 }
158
159 LabelledComboBox {
160 label: qsTr("Size")
161 model: instrumentValueData.factValueGrid.fontSizeNames
162 currentIndex: instrumentValueData.factValueGrid.fontSize
163 onActivated: (index) => { instrumentValueData.factValueGrid.fontSize = index }
164 }
165
166 QGCCheckBoxSlider {
167 Layout.fillWidth: true
168 text: qsTr("Show Units")
169 checked: instrumentValueData.showUnits
170 onClicked: instrumentValueData.showUnits = checked
171 }
172 }
173 }
174
175 SettingsGroupLayout {
176 Layout.alignment: Qt.AlignTop
177 heading: qsTr("Value range")
178
179 ColumnLayout {
180 Layout.fillWidth: true
181
182 RowLayout {
183 Layout.fillWidth: true
184 spacing: ScreenTools.defaultFontPixelWidth * 2
185
186 QGCLabel {
187 Layout.fillWidth: true
188 text: qsTr("Type")
189 }
190
191 QGCComboBox {
192 id: rangeTypeCombo
193 model: instrumentValueData.rangeTypeNames
194 currentIndex: instrumentValueData.rangeType
195 sizeToContents: true
196 onActivated: (index) => { instrumentValueData.rangeType = index }
197 }
198 }
199
200 Loader {
201 id: rangeLoader
202 visible: sourceComponent
203 Layout.columnSpan: 2
204 Layout.alignment: Qt.AlignHCenter
205 Layout.margins: ScreenTools.defaultFontPixelWidth
206 Layout.preferredWidth: item ? item.width : 0
207 Layout.preferredHeight: item ? item.height : 0
208
209 property var instrumentValueData: root.instrumentValueData
210
211 function updateSourceComponent() {
212 switch (instrumentValueData.rangeType) {
213 case InstrumentValueData.NoRangeInfo:
214 sourceComponent = undefined
215 break
216 case InstrumentValueData.ColorRange:
217 sourceComponent = colorRangeDialog
218 break
219 case InstrumentValueData.OpacityRange:
220 sourceComponent = opacityRangeDialog
221 break
222 case InstrumentValueData.IconSelectRange:
223 sourceComponent = iconRangeDialog
224 break
225 }
226 }
227
228 Component.onCompleted: {
229 updateSourceComponent()
230 if (sourceComponent) {
231 height = item.childrenRect.height
232 width = item.childrenRect.width
233 }
234 }
235
236 Connections {
237 target: instrumentValueData
238 onRangeTypeChanged: rangeLoader.updateSourceComponent()
239 }
240 }
241 }
242 }
243 }
244 }
245
246 Component {
247 id: colorRangeDialog
248
249 Item {
250 width: childrenRect.width
251 height: childrenRect.height
252
253 function updateRangeValue(index, text) {
254 var newValues = instrumentValueData.rangeValues
255 newValues[index] = parseFloat(text)
256 instrumentValueData.rangeValues = newValues
257 }
258
259 function updateColorValue(index, color) {
260 var newColors = instrumentValueData.rangeColors
261 newColors[index] = color
262 instrumentValueData.rangeColors = newColors
263 }
264
265 ColorDialog {
266 id: colorPickerDialog
267 modality: Qt.ApplicationModal
268 selectedColor: instrumentValueData.rangeColors.length ? instrumentValueData.rangeColors[colorIndex] : "white"
269 onAccepted: updateColorValue(colorIndex, selectedColor)
270
271 property int colorIndex: 0
272 }
273
274 Column {
275 id: mainColumn
276 spacing: ScreenTools.defaultFontPixelHeight / 2
277
278 QGCLabel {
279 width: rowLayout.width
280 text: qsTr("Specify the color you want to apply based on value ranges. The color will be applied to the icon if available, otherwise to the value itself.")
281 wrapMode: Text.WordWrap
282 }
283
284 Row {
285 id: rowLayout
286 spacing: _margins
287
288 Column {
289 anchors.verticalCenter: parent.verticalCenter
290 spacing: _margins
291
292 Repeater {
293 model: instrumentValueData.rangeValues.length
294
295 QGCColoredImage {
296 width: ScreenTools.implicitTextFieldHeight
297 height: width
298 fillMode: Image.PreserveAspectFit
299 color: QGroundControl.globalPalette.text
300 source: "/res/TrashDelete.svg"
301
302 QGCMouseArea {
303 fillItem: parent
304 onClicked: instrumentValueData.removeRangeValue(index)
305 }
306 }
307 }
308 }
309
310 Column {
311 anchors.verticalCenter: parent.verticalCenter
312 spacing: _margins
313
314 Repeater {
315 model: instrumentValueData.rangeValues.length
316
317 QGCTextField {
318 text: instrumentValueData.rangeValues[index]
319 onEditingFinished: updateRangeValue(index, text)
320 }
321 }
322 }
323
324 Column {
325 spacing: _margins
326 Repeater {
327 model: instrumentValueData.rangeColors
328
329 QGCCheckBox {
330 height: ScreenTools.implicitTextFieldHeight
331 checked: instrumentValueData.isValidColor(instrumentValueData.rangeColors[index])
332 onClicked: updateColorValue(index, checked ? "green" : instrumentValueData.invalidColor())
333 }
334 }
335 }
336
337 Column {
338 spacing: _margins
339 Repeater {
340 model: instrumentValueData.rangeColors
341
342 Rectangle {
343 width: ScreenTools.implicitTextFieldHeight
344 height: width
345 border.color: qgcPal.text
346 color: instrumentValueData.isValidColor(modelData) ? modelData : qgcPal.text
347
348 MouseArea {
349 anchors.fill: parent
350 onClicked: {
351 colorPickerDialog.colorIndex = index
352 colorPickerDialog.open()
353 }
354 }
355 }
356 }
357 }
358 }
359
360 QGCButton {
361 text: qsTr("Add Row")
362 onClicked: instrumentValueData.addRangeValue()
363 }
364 }
365 }
366 }
367
368 Component {
369 id: iconRangeDialog
370
371 Item {
372 width: childrenRect.width
373 height: childrenRect.height
374
375 function updateRangeValue(index, text) {
376 var newValues = instrumentValueData.rangeValues
377 newValues[index] = parseFloat(text)
378 instrumentValueData.rangeValues = newValues
379 }
380
381 function updateIconValue(index, icon) {
382 var newIcons = instrumentValueData.rangeIcons
383 newIcons[index] = icon
384 instrumentValueData.rangeIcons = newIcons
385 }
386
387 Column {
388 id: mainColumn
389 spacing: ScreenTools.defaultFontPixelHeight / 2
390
391 QGCLabel {
392 width: rowLayout.width
393 text: qsTr("Specify the icon you want to display based on value ranges.")
394 wrapMode: Text.WordWrap
395 }
396
397 Row {
398 id: rowLayout
399 spacing: _margins
400
401 Column {
402 anchors.verticalCenter: parent.verticalCenter
403 spacing: _margins
404
405 Repeater {
406 model: instrumentValueData.rangeValues.length
407
408 QGCColoredImage {
409 width: ScreenTools.implicitTextFieldHeight
410 height: width
411 fillMode: Image.PreserveAspectFit
412 color: QGroundControl.globalPalette.text
413 source: "/res/TrashDelete.svg"
414
415 QGCMouseArea {
416 fillItem: parent
417 onClicked: instrumentValueData.removeRangeValue(index)
418 }
419 }
420 }
421 }
422
423 Column {
424 anchors.verticalCenter: parent.verticalCenter
425 spacing: _margins
426
427 Repeater {
428 model: instrumentValueData.rangeValues.length
429
430 QGCTextField {
431 text: instrumentValueData.rangeValues[index]
432 onEditingFinished: updateRangeValue(index, text)
433 }
434 }
435 }
436
437 Column {
438 spacing: _margins
439
440 Repeater {
441 model: instrumentValueData.rangeIcons
442
443 QGCColoredImage {
444 height: ScreenTools.implicitTextFieldHeight
445 width: height
446 source: "/InstrumentValueIcons/" + modelData
447 sourceSize.height: height
448 fillMode: Image.PreserveAspectFit
449 mipmap: true
450 smooth: true
451 color: qgcPal.text
452
453 MouseArea {
454 anchors.fill: parent
455 onClicked: {
456 var updateFunction = function(icon){ updateIconValue(index, icon) }
457 iconPickerDialogFactory.open({ iconNames: instrumentValueData.factValueGrid.iconNames, icon: modelData, updateIconFunction: updateFunction })
458 }
459 }
460 }
461 }
462 }
463 }
464
465 QGCButton {
466 text: qsTr("Add Row")
467 onClicked: instrumentValueData.addRangeValue()
468 }
469 }
470 }
471 }
472
473 Component {
474 id: opacityRangeDialog
475
476 Item {
477 width: childrenRect.width
478 height: childrenRect.height
479
480 function updateRangeValue(index, text) {
481 var newValues = instrumentValueData.rangeValues
482 newValues[index] = parseFloat(text)
483 instrumentValueData.rangeValues = newValues
484 }
485
486 function updateOpacityValue(index, opacity) {
487 var newOpacities = instrumentValueData.rangeOpacities
488 newOpacities[index] = opacity
489 instrumentValueData.rangeOpacities = newOpacities
490 }
491
492 Column {
493 id: mainColumn
494 spacing: ScreenTools.defaultFontPixelHeight / 2
495
496 QGCLabel {
497 width: rowLayout.width
498 text: qsTr("Specify the icon opacity you want based on value ranges.")
499 wrapMode: Text.WordWrap
500 }
501
502 Row {
503 id: rowLayout
504 spacing: _margins
505
506 Column {
507 anchors.verticalCenter: parent.verticalCenter
508 spacing: _margins
509
510 Repeater {
511 model: instrumentValueData.rangeValues.length
512
513 QGCColoredImage {
514 width: ScreenTools.implicitTextFieldHeight
515 height: width
516 fillMode: Image.PreserveAspectFit
517 color: QGroundControl.globalPalette.text
518 source: "/res/TrashDelete.svg"
519
520 QGCMouseArea {
521 fillItem: parent
522 onClicked: instrumentValueData.removeRangeValue(index)
523 }
524 }
525 }
526 }
527
528 Column {
529 anchors.verticalCenter: parent.verticalCenter
530 spacing: _margins
531
532 Repeater {
533 model: instrumentValueData.rangeValues
534
535 QGCTextField {
536 text: modelData
537 onEditingFinished: updateRangeValue(index, text)
538 }
539 }
540 }
541
542 Column {
543 spacing: _margins
544
545 Repeater {
546 model: instrumentValueData.rangeOpacities
547
548 QGCTextField {
549 text: modelData
550 onEditingFinished: updateOpacityValue(index, text)
551 }
552 }
553 }
554 }
555
556 QGCButton {
557 text: qsTr("Add Row")
558 onClicked: instrumentValueData.addRangeValue()
559 }
560 }
561 }
562 }
563
564 QGCPopupDialogFactory {
565 id: iconPickerDialogFactory
566
567 dialogComponent: iconPickerDialog
568 }
569
570 Component {
571 id: iconPickerDialog
572
573 QGCPopupDialog {
574 title: qsTr("Select Icon")
575 buttons: Dialog.Close
576
577 property var iconNames
578 property string icon
579 property var updateIconFunction
580
581 GridLayout {
582 columns: 10
583 columnSpacing: 0
584 rowSpacing: 0
585
586 Repeater {
587 model: iconNames
588
589 Rectangle {
590 height: ScreenTools.minTouchPixels
591 width: height
592 color: currentSelection ? qgcPal.text : qgcPal.window
593
594 property bool currentSelection: icon == modelData
595
596 QGCColoredImage {
597 anchors.centerIn: parent
598 height: parent.height * 0.75
599 width: height
600 source: "/InstrumentValueIcons/" + modelData
601 sourceSize.height: height
602 fillMode: Image.PreserveAspectFit
603 mipmap: true
604 smooth: true
605 color: currentSelection ? qgcPal.window : qgcPal.text
606
607 MouseArea {
608 anchors.fill: parent
609 onClicked: {
610 icon = modelData
611 updateIconFunction(modelData)
612 close()
613 }
614 }
615 }
616 }
617 }
618 }
619 }
620 }
621}