diff --git a/src/QGCPalette.cc b/src/QGCPalette.cc index 770c817537e661821cfdcd4413908b4b585d4816..e74574679a939ecc312ceb98c63d114c63b8ba52 100644 --- a/src/QGCPalette.cc +++ b/src/QGCPalette.cc @@ -24,6 +24,8 @@ QGCPalette::Theme QGCPalette::_theme = QGCPalette::Dark; QMap>> QGCPalette::_colorInfoMap; +QStringList QGCPalette::_colors; + QGCPalette::QGCPalette(QObject* parent) : QObject(parent), _colorGroupEnabled(true) @@ -44,7 +46,7 @@ QGCPalette::~QGCPalette() } } -void QGCPalette::_buildMap(void) +void QGCPalette::_buildMap() { // Light Dark // Disabled Enabled Disabled Enabled diff --git a/src/QGCPalette.h b/src/QGCPalette.h index 51cf85744e32ae1b011e3a793a4cd1bb9de66a6f..8c70d05aa92ba3ff3683499fcc2f15e02832c94b 100644 --- a/src/QGCPalette.h +++ b/src/QGCPalette.h @@ -25,12 +25,22 @@ _colorInfoMap[Light][ColorGroupDisabled][QStringLiteral(#name)] = colorInfo[Light][ColorGroupDisabled]; \ _colorInfoMap[Dark][ColorGroupEnabled][QStringLiteral(#name)] = colorInfo[Dark][ColorGroupEnabled]; \ _colorInfoMap[Dark][ColorGroupDisabled][QStringLiteral(#name)] = colorInfo[Dark][ColorGroupDisabled]; \ + _colors << #name; \ } -#define DEFINE_QGC_COLOR(name, setName) \ - Q_PROPERTY(QColor name READ name WRITE setName NOTIFY paletteChanged) \ - QColor name() const { return _colorInfoMap[_theme][_colorGroupEnabled ? ColorGroupEnabled : ColorGroupDisabled][QStringLiteral(#name)]; } \ - void setName(QColor& color) { _colorInfoMap[_theme][_colorGroupEnabled ? ColorGroupEnabled : ColorGroupDisabled][QStringLiteral(#name)] = color; _signalPaletteChangeToAll(); } +#define DEFINE_QGC_COLOR(NAME, SETNAME) \ + Q_PROPERTY(QColor NAME READ NAME WRITE SETNAME NOTIFY paletteChanged) \ + Q_PROPERTY(QStringList NAME ## Colors READ NAME ## Colors NOTIFY paletteChanged) \ + QColor NAME() const { return _colorInfoMap[_theme][_colorGroupEnabled ? ColorGroupEnabled : ColorGroupDisabled][QStringLiteral(#NAME)]; } \ + QStringList NAME ## Colors() const { \ + QStringList c; \ + c << _colorInfoMap[Light][ColorGroupEnabled][QStringLiteral(#NAME)].name(QColor::HexRgb); \ + c << _colorInfoMap[Light][ColorGroupDisabled][QStringLiteral(#NAME)].name(QColor::HexRgb); \ + c << _colorInfoMap[Dark][ColorGroupEnabled][QStringLiteral(#NAME)].name(QColor::HexRgb); \ + c << _colorInfoMap[Dark][ColorGroupDisabled][QStringLiteral(#NAME)].name(QColor::HexRgb); \ + return c; \ + } \ + void SETNAME(QColor& color) { _colorInfoMap[_theme][_colorGroupEnabled ? ColorGroupEnabled : ColorGroupDisabled][QStringLiteral(#NAME)] = color; _signalPaletteChangeToAll(); } /*! QGCPalette is used in QML ui to expose color properties for the QGC palette. There are two @@ -70,8 +80,9 @@ public: typedef QColor PaletteColorInfo_t[cMaxTheme][cMaxColorGroup]; - Q_PROPERTY(Theme globalTheme READ globalTheme WRITE setGlobalTheme NOTIFY paletteChanged) - Q_PROPERTY(bool colorGroupEnabled READ colorGroupEnabled WRITE setColorGroupEnabled NOTIFY paletteChanged) + Q_PROPERTY(Theme globalTheme READ globalTheme WRITE setGlobalTheme NOTIFY paletteChanged) + Q_PROPERTY(bool colorGroupEnabled READ colorGroupEnabled WRITE setColorGroupEnabled NOTIFY paletteChanged) + Q_PROPERTY(QStringList colors READ colors CONSTANT) DEFINE_QGC_COLOR(window, setWindow) DEFINE_QGC_COLOR(windowShade, setWindowShade) @@ -108,23 +119,25 @@ public: QGCPalette(QObject* parent = nullptr); ~QGCPalette(); - bool colorGroupEnabled (void) const { return _colorGroupEnabled; } - void setColorGroupEnabled (bool enabled); + QStringList colors () const { return _colors; } + bool colorGroupEnabled () const { return _colorGroupEnabled; } + void setColorGroupEnabled (bool enabled); - static Theme globalTheme (void) { return _theme; } - static void setGlobalTheme (Theme newTheme); + static Theme globalTheme () { return _theme; } + static void setGlobalTheme (Theme newTheme); signals: void paletteChanged (); private: - static void _buildMap (void); - static void _signalPaletteChangeToAll (void); - void _signalPaletteChanged (void); - void _themeChanged (void); + static void _buildMap (); + static void _signalPaletteChangeToAll (); + void _signalPaletteChanged (); + void _themeChanged (); static Theme _theme; ///< There is a single theme for all palettes bool _colorGroupEnabled; ///< Currently selected ColorGroup. true: enabled, false: disabled + static QStringList _colors; static QMap>> _colorInfoMap; // theme -> colorGroup -> color name -> color static QList _paletteObjects; ///< List of all active QGCPalette objects diff --git a/src/QmlControls/QmlTest.qml b/src/QmlControls/QmlTest.qml index 4252817e2954b87da81c8f13b73d380bd9988285..0f3797a139a613ef7a1e04557ee337d53890ff30 100644 --- a/src/QmlControls/QmlTest.qml +++ b/src/QmlControls/QmlTest.qml @@ -72,10 +72,38 @@ Rectangle { palette.globalTheme = oldTheme; palette.colorGroupEnabled = true; - var jsonString = JSON.stringify(themeObj); + var jsonString = JSON.stringify(themeObj, null, 4); themeImportExportEdit.text = jsonString - paletteImportExportPopup.open() + } + + function exportThemeCPP() { + var palToExport = "" + for(var i = 0; i < palette.colors.length; i++) { + var cs = palette.colors[i] + var csc = cs + 'Colors' + palToExport += 'DECLARE_QGC_COLOR(' + cs + ', \"' + palette[csc][0] + '\", \"' + palette[csc][1] + '\", \"' + palette[csc][2] + '\", \"' + palette[csc][3] + '\")\n' + } + themeImportExportEdit.text = palToExport + } + + function exportThemePlugin() { + var palToExport = "" + for(var i = 0; i < palette.colors.length; i++) { + var cs = palette.colors[i] + var csc = cs + 'Colors' + if(i > 0) { + palToExport += '\nelse ' + } + palToExport += + 'if (colorName == QStringLiteral(\"' + cs + '\")) {\n' + + ' colorInfo[QGCPalette::Dark][QGCPalette::ColorGroupEnabled] = QColor(\"' + palette[csc][0] + '\");\n' + + ' colorInfo[QGCPalette::Dark][QGCPalette::ColorGroupDisabled] = QColor(\"' + palette[csc][1] + '\");\n' + + ' colorInfo[QGCPalette::Light][QGCPalette::ColorGroupEnabled] = QColor(\"' + palette[csc][2] + '\");\n' + + ' colorInfo[QGCPalette::Light][QGCPalette::ColorGroupDisabled] = QColor(\"' + palette[csc][3] + '\");\n' + + '}' + } + themeImportExportEdit.text = palToExport } function importTheme(jsonStr) { @@ -101,30 +129,64 @@ Rectangle { } Popup { - id: paletteImportExportPopup - focus: true - parent: Overlay.overlay - x: (_root.width - width)/2 - y: (_root.height - height)/2 - width: _root.width * 0.666 - height: _root.height * 0.666 - modal: true + id: paletteImportExportPopup + width: impCol.width + (ScreenTools.defaultFontPixelWidth * 4) + height: impCol.height + (ScreenTools.defaultFontPixelHeight * 2) + modal: true + focus: true + parent: Overlay.overlay + closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside + x: Math.round((mainWindow.width - width) * 0.5) + y: Math.round((mainWindow.height - height) * 0.5) + onVisibleChanged: { + if(visible) { + _header.exportTheme() + _jsonButton.checked = true + } + } + background: Rectangle { + anchors.fill: parent + color: palette.window + radius: ScreenTools.defaultFontPixelHeight * 0.5 + border.width: 1 + border.color: palette.text + } Column { - anchors.fill: parent - spacing: 5 - + id: impCol + spacing: ScreenTools.defaultFontPixelHeight + anchors.centerIn: parent + Row { + id: exportFormats + spacing: ScreenTools.defaultFontPixelWidth * 2 + anchors.horizontalCenter: parent.horizontalCenter + QGCRadioButton { + id: _jsonButton + text: "Json" + onClicked: _header.exportTheme() + } + QGCRadioButton { + text: "QGC" + onClicked: _header.exportThemeCPP() + } + QGCRadioButton { + text: "Custom Plugin" + onClicked: _header.exportThemePlugin() + } + } Rectangle { - width: parent.width - height: parent.height - importButton.height - border.width: 1 - + width: flick.width + (ScreenTools.defaultFontPixelWidth * 2) + height: flick.height + (ScreenTools.defaultFontPixelHeight * 2) + color: "white" + anchors.margins: 10 Flickable { - id: flick - - anchors.fill: parent - contentWidth: themeImportExportEdit.paintedWidth - contentHeight: themeImportExportEdit.paintedHeight - clip: true + id: flick + clip: true + width: mainWindow.width * 0.666 + height: mainWindow.height * 0.666 + contentWidth: themeImportExportEdit.paintedWidth + contentHeight: themeImportExportEdit.paintedHeight + anchors.centerIn: parent + flickableDirection: Flickable.VerticalFlick function ensureVisible(r) { @@ -139,19 +201,31 @@ Rectangle { } TextEdit { - id: themeImportExportEdit - width: flick.width - focus: true - wrapMode: TextEdit.Wrap + id: themeImportExportEdit + width: flick.width + focus: true + font.family: ScreenTools.fixedFontFamily + font.pointSize: ScreenTools.defaultFontPointSize onCursorRectangleChanged: flick.ensureVisible(cursorRectangle) } } } - Button { - id: importButton - text: "Import" - onPressed: { - _header.importTheme(themeImportExportEdit.text); + Row { + spacing: ScreenTools.defaultFontPixelWidth * 2 + anchors.horizontalCenter: parent.horizontalCenter + QGCButton { + id: importButton + text: "Import (Json Only)" + enabled: themeImportExportEdit.text[0] === "{" && _jsonButton.checked + onClicked: { + _header.importTheme(themeImportExportEdit.text); + } + } + QGCButton { + text: "Close" + onClicked: { + paletteImportExportPopup.close() + } } } } @@ -164,7 +238,7 @@ Rectangle { height: 30 anchors.left: windowColorLabel.right anchors.leftMargin: 20 - onPressed: _header.exportTheme() + onPressed: paletteImportExportPopup.open() } Row { diff --git a/src/QmlControls/ToolStrip.qml b/src/QmlControls/ToolStrip.qml index 1222862d751b2ae86f8e09ee067fd49b31718ba4..50f6fd0e5ceef4167930a2f2b48926bdee154d68 100644 --- a/src/QmlControls/ToolStrip.qml +++ b/src/QmlControls/ToolStrip.qml @@ -31,7 +31,7 @@ Rectangle { property AbstractButton lastClickedButton: null - // Ensure we don't get lower than + // Ensure we don't get narrower than content property real _idealWidth: (ScreenTools.isMobile ? ScreenTools.minTouchPixels : ScreenTools.defaultFontPixelWidth * 8) + toolStripColumn.anchors.margins * 2 signal clicked(int index, bool checked)