6import QGroundControl.Controls
11 anchors.margins: ScreenTools.defaultFontPixelWidth
14 QGCPalette { id: qgcPal }
16 property var enabledPalette: QGCPalette { colorGroupEnabled: true }
17 property var disabledPalette: QGCPalette { colorGroupEnabled: false }
19 function exportPaletteColors(pal) {
21 for(var clrName in pal) {
22 if(pal[clrName].r !== undefined) {
23 objToExport[clrName] = pal[clrName].toString();
29 function fillPalette(pal, colorsObj) {
30 for(var clrName in colorsObj) {
31 pal[clrName] = colorsObj[clrName];
35 function exportTheme() {
36 var themeObj = {"light": {}, "dark":{}}
37 var oldTheme = qgcPal.globalTheme;
39 qgcPal.globalTheme = QGCPalette.Light
40 qgcPal.colorGroupEnabled = true
41 themeObj.light["enabled"] = exportPaletteColors(qgcPal);
42 qgcPal.colorGroupEnabled = false
43 themeObj.light["disabled"] = exportPaletteColors(qgcPal);
44 qgcPal.globalTheme = QGCPalette.Dark
45 qgcPal.colorGroupEnabled = true
46 themeObj.dark["enabled"] = exportPaletteColors(qgcPal);
47 qgcPal.colorGroupEnabled = false
48 themeObj.dark["disabled"] = exportPaletteColors(qgcPal);
50 qgcPal.globalTheme = oldTheme;
51 qgcPal.colorGroupEnabled = true;
53 var jsonString = JSON.stringify(themeObj, null, 4);
55 themeImportExportEdit.text = jsonString
58 function exportThemeCPP() {
60 for(var i = 0; i < qgcPal.colors.length; i++) {
61 var cs = qgcPal.colors[i]
62 var csc = cs + 'Colors'
63 palToExport += 'DECLARE_QGC_COLOR(' + cs + ', \"' + qgcPal[csc][1] + '\", \"' + qgcPal[csc][0] + '\", \"' + qgcPal[csc][3] + '\", \"' + qgcPal[csc][2] + '\")\n'
65 themeImportExportEdit.text = palToExport
68 function exportThemePlugin() {
70 for(var i = 0; i < qgcPal.colors.length; i++) {
71 var cs = qgcPal.colors[i]
72 var csc = cs + 'Colors'
74 palToExport += '\nelse '
77 'if (colorName == QStringLiteral(\"' + cs + '\")) {\n' +
78 ' colorInfo[QGCPalette::Dark][QGCPalette::ColorGroupEnabled] = QColor(\"' + qgcPal[csc][2] + '\");\n' +
79 ' colorInfo[QGCPalette::Dark][QGCPalette::ColorGroupDisabled] = QColor(\"' + qgcPal[csc][3] + '\");\n' +
80 ' colorInfo[QGCPalette::Light][QGCPalette::ColorGroupEnabled] = QColor(\"' + qgcPal[csc][0] + '\");\n' +
81 ' colorInfo[QGCPalette::Light][QGCPalette::ColorGroupDisabled] = QColor(\"' + qgcPal[csc][1] + '\");\n' +
84 themeImportExportEdit.text = palToExport
87 function importTheme(jsonStr) {
88 var jsonObj = JSON.parse(jsonStr)
89 var themeObj = {"light": {}, "dark":{}}
90 var oldTheme = qgcPal.globalTheme;
92 qgcPal.globalTheme = QGCPalette.Light
93 qgcPal.colorGroupEnabled = true
94 fillPalette(qgcPal, jsonObj.light.enabled)
95 qgcPal.colorGroupEnabled = false
96 fillPalette(qgcPal, jsonObj.light.disabled);
97 qgcPal.globalTheme = QGCPalette.Dark
98 qgcPal.colorGroupEnabled = true
99 fillPalette(qgcPal, jsonObj.dark.enabled);
100 qgcPal.colorGroupEnabled = false
101 fillPalette(qgcPal, jsonObj.dark.disabled);
103 qgcPal.globalTheme = oldTheme;
104 qgcPal.colorGroupEnabled = true;
106 paletteImportExportPopup.close()
109 //-------------------------------------------------------------------------
112 id: paletteImportExportPopup
113 width: impCol.width + (ScreenTools.defaultFontPixelWidth * 4)
114 height: impCol.height + (ScreenTools.defaultFontPixelHeight * 2)
117 parent: Overlay.overlay
118 closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
119 x: Math.round((mainWindow.width - width) * 0.5)
120 y: Math.round((mainWindow.height - height) * 0.5)
124 _jsonButton.checked = true
127 background: Rectangle {
130 radius: ScreenTools.defaultFontPixelHeight * 0.5
132 border.color: qgcPal.text
136 spacing: ScreenTools.defaultFontPixelHeight
137 anchors.centerIn: parent
140 spacing: ScreenTools.defaultFontPixelWidth * 2
141 anchors.horizontalCenter: parent.horizontalCenter
145 onClicked: exportTheme()
149 onClicked: exportThemeCPP()
152 text: "Custom Plugin"
153 onClicked: exportThemePlugin()
157 width: flick.width + (ScreenTools.defaultFontPixelWidth * 2)
158 height: flick.height + (ScreenTools.defaultFontPixelHeight * 2)
164 width: mainWindow.width * 0.666
165 height: mainWindow.height * 0.666
166 contentWidth: themeImportExportEdit.paintedWidth
167 contentHeight: themeImportExportEdit.paintedHeight
168 anchors.centerIn: parent
169 flickableDirection: Flickable.VerticalFlick
171 function ensureVisible(r)
175 else if (contentX+width <= r.x+r.width)
176 contentX = r.x+r.width-width;
179 else if (contentY+height <= r.y+r.height)
180 contentY = r.y+r.height-height;
184 id: themeImportExportEdit
187 font.family: ScreenTools.fixedFontFamily
188 font.pointSize: ScreenTools.defaultFontPointSize
189 onCursorRectangleChanged: flick.ensureVisible(cursorRectangle)
194 spacing: ScreenTools.defaultFontPixelWidth * 2
195 anchors.horizontalCenter: parent.horizontalCenter
198 text: "Import (Json Only)"
199 enabled: themeImportExportEdit.text[0] === "{" && _jsonButton.checked
201 importTheme(themeImportExportEdit.text);
207 paletteImportExportPopup.close()
214 //-------------------------------------------------------------------------
219 height: themeChoice.height * 2
221 anchors.top: parent.top
225 anchors.centerIn: parent
227 text: qsTr("Window Color")
228 anchors.verticalCenter: parent.verticalCenter
231 text: qsTr("Import/Export")
232 anchors.verticalCenter: parent.verticalCenter
233 onClicked: paletteImportExportPopup.open()
237 anchors.verticalCenter: parent.verticalCenter
240 checked: qgcPal.globalTheme === QGCPalette.Light
242 qgcPal.globalTheme = QGCPalette.Light
247 checked: qgcPal.globalTheme === QGCPalette.Dark
249 qgcPal.globalTheme = QGCPalette.Dark
255 //-------------------------------------------------------------------------
258 anchors.top: _header.bottom
259 anchors.bottom: parent.bottom
261 contentWidth: _rootCol.width
262 contentHeight: _rootCol.height
268 // Edit theme GroupBox
270 title: "Preview and edit theme"
274 property size cellSize: "90x25"
279 width: editRoot.cellSize.width * 2
280 height: editRoot.cellSize.height
284 width: editRoot.cellSize.width; height: editRoot.cellSize.height
286 horizontalAlignment: Text.AlignLeft
287 text: qsTr("Enabled")
290 width: editRoot.cellSize.width; height: editRoot.cellSize.height
292 horizontalAlignment: Text.AlignHCenter
296 width: editRoot.cellSize.width; height: editRoot.cellSize.height
298 horizontalAlignment: Text.AlignHCenter
299 text: qsTr("Disabled")
302 width: editRoot.cellSize.width; height: editRoot.cellSize.height
304 horizontalAlignment: Text.AlignHCenter
309 // Populate the model with all color names in the global palette
310 Component.onCompleted: {
311 for(var colorNameStr in enabledPalette) {
312 if(enabledPalette[colorNameStr].r !== undefined) {
313 paletteColorList.append({ colorName: colorNameStr });
322 // Reproduce all the models
324 model: paletteColorList
328 width: editRoot.cellSize.width * 2
329 height: editRoot.cellSize.height
330 horizontalAlignment: Text.AlignRight
331 verticalAlignment: Text.AlignVCenter
336 id: enabledColorPicker
337 color: enabledPalette[colorName]
338 onColorSelected: enabledPalette[colorName] = color
342 width: editRoot.cellSize.width; height: editRoot.cellSize.height
343 inputMask: "\\#>HHHHHHhh;"
344 horizontalAlignment: Text.AlignLeft
345 text: enabledPalette[colorName]
346 onEditingFinished: enabledPalette[colorName] = text
349 id: disabledColorPicker
350 color: disabledPalette[colorName]
351 onColorSelected: disabledPalette[colorName] = color
354 width: editRoot.cellSize.width; height: editRoot.cellSize.height
355 inputMask: enabledTextField.inputMask
356 horizontalAlignment: Text.AlignLeft
357 text: disabledPalette[colorName]
358 onEditingFinished: disabledPalette[colorName] = text
363 } // GroupBox { title: "Preview and edit theme"
365 // QGC controls preview
366 GroupBox { title: "Controls preview"
369 property real _colWidth: ScreenTools.defaultFontPointSize * 18
370 property real _height: _colWidth*0.15
371 property color _bkColor: qgcPal.window
373 width: previewGrid.width
381 width: ctlPrevColumn._colWidth
382 height: ctlPrevColumn._height
384 horizontalAlignment: Text.AlignHCenter
385 text: qsTr("QGC name")
388 width: ctlPrevColumn._colWidth
389 height: ctlPrevColumn._height
391 horizontalAlignment: Text.AlignHCenter
392 text: qsTr("Enabled")
395 width: ctlPrevColumn._colWidth
396 height: ctlPrevColumn._height
398 horizontalAlignment: Text.AlignHCenter
399 text: qsTr("Disabled")
404 sourceComponent: ctlRowHeader
405 property string text: "QGCLabel"
408 width: ctlPrevColumn._colWidth
409 height: ctlPrevColumn._height
410 color: ctlPrevColumn._bkColor
418 width: ctlPrevColumn._colWidth
419 height: ctlPrevColumn._height
420 color: ctlPrevColumn._bkColor
431 sourceComponent: ctlRowHeader
432 property string text: "QGCButton"
435 width: ctlPrevColumn._colWidth
436 height: ctlPrevColumn._height
440 width: ctlPrevColumn._colWidth
441 height: ctlPrevColumn._height
446 // QGCButton - primary
448 sourceComponent: ctlRowHeader
449 property string text: "QGCButton(primary)"
452 width: ctlPrevColumn._colWidth
453 height: ctlPrevColumn._height
458 width: ctlPrevColumn._colWidth
459 height: ctlPrevColumn._height
465 // ToolStripHoverButton
467 sourceComponent: ctlRowHeader
468 property string text: "ToolStripHoverButton"
470 ToolStripHoverButton {
471 width: ctlPrevColumn._colWidth
472 height: ctlPrevColumn._height * 2
473 text: qsTr("Hover Button")
474 radius: ScreenTools.defaultFontPointSize
475 imageSource: "/qmlimages/Gears.svg"
477 ToolStripHoverButton {
478 width: ctlPrevColumn._colWidth
479 height: ctlPrevColumn._height * 2
480 text: qsTr("Hover Button")
481 radius: ScreenTools.defaultFontPointSize
482 imageSource: "/qmlimages/Gears.svg"
488 sourceComponent: ctlRowHeader
489 property string text: "QGCButton(menu)"
504 width: ctlPrevColumn._colWidth
505 height: ctlPrevColumn._height
507 onClicked: buttonMenu.popup()
510 width: ctlPrevColumn._colWidth
511 height: ctlPrevColumn._height
514 onClicked: buttonMenu.popup()
519 sourceComponent: ctlRowHeader
520 property string text: "QGCRadioButton"
523 width: ctlPrevColumn._colWidth
524 height: ctlPrevColumn._height
525 color: ctlPrevColumn._bkColor
533 width: ctlPrevColumn._colWidth
534 height: ctlPrevColumn._height
535 color: ctlPrevColumn._bkColor
546 sourceComponent: ctlRowHeader
547 property string text: "QGCCheckBox"
550 width: ctlPrevColumn._colWidth
551 height: ctlPrevColumn._height
552 color: ctlPrevColumn._bkColor
556 text: qsTr("Check Box")
560 width: ctlPrevColumn._colWidth
561 height: ctlPrevColumn._height
562 color: ctlPrevColumn._bkColor
566 text: qsTr("Check Box")
573 sourceComponent: ctlRowHeader
574 property string text: "QGCCheckBoxSlider"
577 width: ctlPrevColumn._colWidth
578 height: ctlPrevColumn._height
579 color: ctlPrevColumn._bkColor
583 text: qsTr("Check Box Slider")
587 width: ctlPrevColumn._colWidth
588 height: ctlPrevColumn._height
589 color: ctlPrevColumn._bkColor
593 text: qsTr("Check Box Slider")
600 sourceComponent: ctlRowHeader
601 property string text: "QGCTextField"
604 width: ctlPrevColumn._colWidth
605 height: ctlPrevColumn._height
609 width: ctlPrevColumn._colWidth
610 height: ctlPrevColumn._height
617 sourceComponent: ctlRowHeader
618 property string text: "QGCComboBox"
621 width: ctlPrevColumn._colWidth
622 height: ctlPrevColumn._height
623 model: [ qsTr("Item 1"), qsTr("Item 2"), qsTr("Item 3") ]
626 width: ctlPrevColumn._colWidth
627 height: ctlPrevColumn._height
628 model: [ qsTr("Item 1"), qsTr("Item 2"), qsTr("Item 3") ]
634 sourceComponent: ctlRowHeader
635 property string text: "SubMenuButton"
638 width: ctlPrevColumn._colWidth
639 height: ctlPrevColumn._colWidth/3
640 text: qsTr("SUB MENU")
643 width: ctlPrevColumn._colWidth
644 height: ctlPrevColumn._colWidth/3
645 text: qsTr("SUB MENU")
650 width: previewGrid.width
653 color: qgcPal.alertBackground
654 border.color: qgcPal.alertBorder
656 anchors.horizontalCenter: parent.horizontalCenter
658 text: "Alert Message"
659 color: qgcPal.alertText
660 anchors.centerIn: parent
664 } // GroupBox { title: "Controls preview"
674 anchors.horizontalCenter: parent.horizontalCenter
676 property color backgroundColor: qgcPal.window
677 sourceComponent: arbBox
680 property color backgroundColor: qgcPal.windowShade
681 sourceComponent: arbBox
684 property color backgroundColor: qgcPal.windowShadeDark
685 sourceComponent: arbBox
694 // SettingsGroupLayout Test
696 title: "SettingsGroupLayout Test"
697 anchors.horizontalCenter: parent.horizontalCenter
699 background: Rectangle {
701 border.color: qgcPal.text
706 spacing: ScreenTools.defaultFontPixelHeight
708 // Controls for testing properties
710 spacing: ScreenTools.defaultFontPixelWidth * 2
719 id: showDividersCheck
731 id: showDescriptionCheck
732 text: "Show Description"
738 spacing: ScreenTools.defaultFontPixelWidth * 2
740 QGCLabel { text: "Visibility toggles:"; font.bold: true }
768 spacing: ScreenTools.defaultFontPixelWidth * 2
770 QGCLabel { text: "Repeater toggles:"; font.bold: true }
773 id: repeaterShowDividers
809 // Test SettingsGroupLayout with various content
810 SettingsGroupLayout {
811 width: ScreenTools.defaultFontPixelWidth * 60
812 heading: showHeadingCheck.checked ? "Test Settings Group" : ""
813 headingDescription: showDescriptionCheck.checked ? "This is a description of the settings group that explains what these settings are for." : ""
814 showBorder: showBorderCheck.checked
815 showDividers: showDividersCheck.checked
818 Layout.fillWidth: true
819 visible: item1Visible.checked
823 Layout.fillWidth: true
827 Layout.preferredWidth: ScreenTools.defaultFontPixelWidth * 15
832 Layout.fillWidth: true
833 visible: item2Visible.checked
837 Layout.fillWidth: true
840 model: ["Option 1", "Option 2", "Option 3"]
841 Layout.preferredWidth: ScreenTools.defaultFontPixelWidth * 15
846 Layout.fillWidth: true
847 visible: item3Visible.checked
850 text: "Enable feature"
851 Layout.fillWidth: true
856 Layout.fillWidth: true
857 visible: item4Visible.checked
861 Layout.fillWidth: true
869 // Nested SettingsGroupLayout test
871 text: "Nested SettingsGroupLayout:"
875 SettingsGroupLayout {
876 width: ScreenTools.defaultFontPixelWidth * 60
877 heading: "Outer Group"
882 Layout.fillWidth: true
883 QGCLabel { text: "Outer setting"; Layout.fillWidth: true }
884 QGCTextField { text: "Value" }
887 SettingsGroupLayout {
888 Layout.fillWidth: true
889 heading: "Inner Group"
890 headingDescription: "Nested group inside outer group"
895 text: "Inner checkbox 1"
896 Layout.fillWidth: true
900 text: "Inner checkbox 2"
901 Layout.fillWidth: true
906 Layout.fillWidth: true
907 QGCLabel { text: "Another outer setting"; Layout.fillWidth: true }
908 QGCComboBox { model: ["A", "B", "C"] }
912 // Test with Repeater
914 text: "SettingsGroupLayout with Repeater:"
918 SettingsGroupLayout {
919 width: ScreenTools.defaultFontPixelWidth * 60
920 heading: "Repeater Test"
922 showDividers: repeaterShowDividers.checked
926 delegate: RowLayout {
927 Layout.fillWidth: true
930 case 0: return repeater1Visible.checked
931 case 1: return repeater2Visible.checked
932 case 2: return repeater3Visible.checked
933 case 3: return repeater4Visible.checked
934 case 4: return repeater5Visible.checked
939 text: "Repeated Item " + (index + 1) + ":"
940 Layout.fillWidth: true
943 text: "Value " + (index + 1)
944 Layout.preferredWidth: ScreenTools.defaultFontPixelWidth * 15
959 width: ctlPrevColumn._colWidth
960 height: ctlPrevColumn._height
964 text: parent.parent.text
966 horizontalAlignment: Text.AlignRight
967 verticalAlignment: Text.AlignVCenter
975 width: arbGrid.width * 1.5
976 height: arbGrid.height * 1.5
977 color: backgroundColor
978 border.color: qgcPal.text
980 anchors.horizontalCenter: parent.horizontalCenter
985 anchors.centerIn: parent
987 color: qgcPal.colorGreen
988 width: ScreenTools.defaultFontPixelWidth * 2
990 sourceSize.height: width
992 fillMode: Image.PreserveAspectFit
993 source: "/qmlimages/Gears.svg"
995 Label { text: "colorGreen"; color: qgcPal.colorGreen; }
997 color: qgcPal.colorOrange
998 width: ScreenTools.defaultFontPixelWidth * 2
1000 sourceSize.height: width
1002 fillMode: Image.PreserveAspectFit
1003 source: "/qmlimages/Gears.svg"
1005 Label { text: "colorOrange"; color: qgcPal.colorOrange; }
1007 color: qgcPal.colorRed
1008 width: ScreenTools.defaultFontPixelWidth * 2
1010 sourceSize.height: width
1012 fillMode: Image.PreserveAspectFit
1013 source: "/qmlimages/Gears.svg"
1015 Label { text: "colorRed"; color: qgcPal.colorRed; }
1017 color: qgcPal.colorGrey
1018 width: ScreenTools.defaultFontPixelWidth * 2
1020 sourceSize.height: width
1022 fillMode: Image.PreserveAspectFit
1023 source: "/qmlimages/Gears.svg"
1025 Label { text: "colorGrey"; color: qgcPal.colorGrey; }
1027 color: qgcPal.colorBlue
1028 width: ScreenTools.defaultFontPixelWidth * 2
1030 sourceSize.height: width
1032 fillMode: Image.PreserveAspectFit
1033 source: "/qmlimages/Gears.svg"
1035 Label { text: "colorBlue"; color: qgcPal.colorBlue; }