From 5fd125d9d643e8a52ff9db809b0f63553c15fb90 Mon Sep 17 00:00:00 2001 From: Don Gagne Date: Wed, 4 Feb 2015 14:04:01 -0800 Subject: [PATCH] Add Light/Dark theme support to QML --- .../FactControls/FactCheckBox.qml | 4 +- qml/QGroundControl/FactControls/FactLabel.qml | 5 +- .../FactControls/FactTextField.qml | 7 +- src/QGCApplication.cc | 3 + src/QGCPalette.cc | 122 +++++++++--------- src/QGCPalette.h | 73 +++++------ 6 files changed, 108 insertions(+), 106 deletions(-) diff --git a/qml/QGroundControl/FactControls/FactCheckBox.qml b/qml/QGroundControl/FactControls/FactCheckBox.qml index ea8252161..82a29a713 100644 --- a/qml/QGroundControl/FactControls/FactCheckBox.qml +++ b/qml/QGroundControl/FactControls/FactCheckBox.qml @@ -8,6 +8,8 @@ CheckBox { property variant checkedValue: 1 property variant uncheckedValue: 0 + property var __qgcpal: QGCPalette { colorGroup: QGCPalette.Active } + partiallyCheckedEnabled: fact.value != checkedValue && fact.value != uncheckedValue checkedState: fact.value == checkedValue ? Qt.Checked : (fact.value == uncheckedValue ? Qt.Unchecked : Qt.PartiallyChecked) @@ -19,7 +21,7 @@ CheckBox { style: CheckBoxStyle { label: Text { - color: palette.windowText + color: __qgcpal.windowText text: control.text } } diff --git a/qml/QGroundControl/FactControls/FactLabel.qml b/qml/QGroundControl/FactControls/FactLabel.qml index c883c7174..25bcf8099 100644 --- a/qml/QGroundControl/FactControls/FactLabel.qml +++ b/qml/QGroundControl/FactControls/FactLabel.qml @@ -5,9 +5,10 @@ import QGroundControl.FactSystem 1.0 Label { property Fact fact: Fact { value: "FactLabel" } - QGCPalette { id: palette; colorGroup: QGCPalette.Active } - color: palette.windowText + property var __qgcpal: QGCPalette { colorGroup: QGCPalette.Active } + + color: __qgcpal.windowText text: fact.valueString } diff --git a/qml/QGroundControl/FactControls/FactTextField.qml b/qml/QGroundControl/FactControls/FactTextField.qml index 8e62a878d..be0e68e66 100644 --- a/qml/QGroundControl/FactControls/FactTextField.qml +++ b/qml/QGroundControl/FactControls/FactTextField.qml @@ -6,10 +6,11 @@ import QGroundControl.FactSystem 1.0 TextField { property Fact fact: Fact { value: 0 } property bool showUnits: false - QGCPalette { id: palette; colorGroup: enabled ? QGCPalette.Active : QGCPalette.Disabled } + + property var __qgcpal: QGCPalette { colorGroup: QGCPalette.Active } text: fact.valueString - textColor: palette.text + textColor: __qgcpal.text Label { id: unitsLabelWidthGenerator @@ -32,7 +33,7 @@ TextField { anchors.fill: parent border.color: control.activeFocus ? "#47b" : "#999" - color: palette.base + color: __qgcpal.base } Text { diff --git a/src/QGCApplication.cc b/src/QGCApplication.cc index cdc054ded..f383226e6 100644 --- a/src/QGCApplication.cc +++ b/src/QGCApplication.cc @@ -57,6 +57,7 @@ #include "AutoPilotPluginManager.h" #include "QGCTemporaryFile.h" #include "QGCFileDialog.h" +#include "QGCPalette.h" #ifdef QGC_RTLAB_ENABLED #include "OpalLink.h" @@ -537,6 +538,8 @@ void QGCApplication::_loadCurrentStyle(void) setStyle("plastique"); } + QGCPalette::setGlobalTheme(_styleIsDark ? QGCPalette::Dark : QGCPalette::Light); + // Finally restore the cursor before returning. restoreOverrideCursor(); } diff --git a/src/QGCPalette.cc b/src/QGCPalette.cc index 3e3b73925..46f54bda1 100644 --- a/src/QGCPalette.cc +++ b/src/QGCPalette.cc @@ -29,77 +29,58 @@ #include #include -bool QGCPalette::_paletteLoaded = false; - -QColor QGCPalette::_alternateBase[QGCPalette::_cColorGroups]; -QColor QGCPalette::_base[QGCPalette::_cColorGroups]; -QColor QGCPalette::_button[QGCPalette::_cColorGroups]; -QColor QGCPalette::_buttonText[QGCPalette::_cColorGroups]; -QColor QGCPalette::_dark[QGCPalette::_cColorGroups]; -QColor QGCPalette::_highlight[QGCPalette::_cColorGroups]; -QColor QGCPalette::_highlightedText[QGCPalette::_cColorGroups]; -QColor QGCPalette::_light[QGCPalette::_cColorGroups]; -QColor QGCPalette::_mid[QGCPalette::_cColorGroups]; -QColor QGCPalette::_midlight[QGCPalette::_cColorGroups]; -QColor QGCPalette::_shadow[QGCPalette::_cColorGroups]; -QColor QGCPalette::_text[QGCPalette::_cColorGroups]; -QColor QGCPalette::_window[QGCPalette::_cColorGroups]; -QColor QGCPalette::_windowText[QGCPalette::_cColorGroups]; +QList QGCPalette::_paletteObjects; + +QGCPalette::Theme QGCPalette::_theme = QGCPalette::Dark; + +QColor QGCPalette::_alternateBase[QGCPalette::_cThemes][QGCPalette::_cColorGroups] = { + { QColor(0xF6, 0xF6, 0xF6), QColor(0xF6, 0xF6, 0xF6), QColor(0xF6, 0xF6, 0xF6) }, + { QColor(2, 2, 2), QColor(2, 2, 2), QColor(2, 2, 2) } +}; + +QColor QGCPalette::_base[QGCPalette::_cThemes][QGCPalette::_cColorGroups] = { + { QColor(0xF6, 0xF6, 0xF6), QColor(0xF6, 0xF6, 0xF6), QColor(0xF6, 0xF6, 0xF6) }, + { QColor(2, 2, 2), QColor(2, 2, 2), QColor(2, 2, 2) } +}; + +QColor QGCPalette::_button[QGCPalette::_cThemes][QGCPalette::_cColorGroups] = { + { QColor(0x58, 0x58, 0x58), QColor(0x1b, 0x6f, 0xad), QColor(0x1b, 0x6f, 0xad) }, + { QColor(0x58, 0x58, 0x58), QColor(0x1b, 0x6f, 0xad), QColor(0x1b, 0x6f, 0xad) }, +}; + +QColor QGCPalette::_buttonText[QGCPalette::_cThemes][QGCPalette::_cColorGroups] = { + { QColor(0, 0, 0), QColor(0xFF, 0xFF, 0xFF), QColor(0xFF, 0xFF, 0xFF) }, + { QColor(0, 0, 0), QColor(0xFF, 0xFF, 0xFF), QColor(0xFF, 0xFF, 0xFF) }, +}; + +QColor QGCPalette::_text[QGCPalette::_cThemes][QGCPalette::_cColorGroups] = { + { QColor(0, 0, 0), QColor(0, 0, 0), QColor(0, 0, 0) }, + { QColor(0xFF, 0xFF, 0xFF), QColor(0xFF, 0xFF, 0xFF), QColor(0xFF, 0xFF, 0xFF) } +}; + +QColor QGCPalette::_window[QGCPalette::_cThemes][QGCPalette::_cColorGroups] = { + { QColor(0xF6, 0xF6, 0xF6), QColor(0xF6, 0xF6, 0xF6), QColor(0xF6, 0xF6, 0xF6) }, + { QColor(0x22, 0x22, 0x22), QColor(0x22, 0x22, 0x22), QColor(0x22, 0x22, 0x22) } +}; + +QColor QGCPalette::_windowText[QGCPalette::_cThemes][QGCPalette::_cColorGroups] = { + { QColor(0, 0, 0), QColor(0, 0, 0), QColor(0, 0, 0) }, + { QColor(0xFF, 0xFF, 0xFF), QColor(0xFF, 0xFF, 0xFF), QColor(0xFF, 0xFF, 0xFF) } +}; QGCPalette::QGCPalette(QObject* parent) : QObject(parent), _colorGroup(Active) { - if (!_paletteLoaded) { - _paletteLoaded = true; - - struct Group2Group { - ColorGroup qgcColorGroup; - QPalette::ColorGroup qtColorGroup; - }; - - static struct Group2Group rgGroup2Group[] = { - { Disabled, QPalette::Disabled }, - { Active, QPalette::Active }, - { Inactive, QPalette::Inactive } - }; - static const size_t crgGroup2Group = sizeof(rgGroup2Group) / sizeof(rgGroup2Group[0]); - Q_ASSERT(crgGroup2Group == _cColorGroups); - - for (size_t i=0; iqtColorGroup); - - ColorGroup qgcColorGroup = prgGroup2Group->qgcColorGroup; - - _alternateBase[qgcColorGroup] = syspal.color(QPalette::AlternateBase); - _base[qgcColorGroup] = syspal.color(QPalette::Base); - _button[qgcColorGroup] = syspal.color(QPalette::Button); - _buttonText[qgcColorGroup] = syspal.color(QPalette::ButtonText); - _text[qgcColorGroup] = syspal.color(QPalette::Text); - - _shadow[qgcColorGroup] = syspal.shadow().color(); - _dark[qgcColorGroup] = syspal.dark().color(); - _highlight[qgcColorGroup] = syspal.highlight().color(); - _highlightedText[qgcColorGroup] = syspal.highlightedText().color(); - _light[qgcColorGroup] = syspal.light().color(); - _mid[qgcColorGroup] = syspal.mid().color(); - _midlight[qgcColorGroup] = syspal.midlight().color(); - } - } + // We have to keep track of all QGCPalette objects in the system so we can signal theme change to all of them + _paletteObjects += this; } QGCPalette::~QGCPalette() { - + bool fSuccess = _paletteObjects.removeOne(this); + Q_ASSERT(fSuccess); + Q_UNUSED(fSuccess); } void QGCPalette::setColorGroup(ColorGroup colorGroup) @@ -107,3 +88,20 @@ void QGCPalette::setColorGroup(ColorGroup colorGroup) _colorGroup = colorGroup; emit paletteChanged(); } + +void QGCPalette::setGlobalTheme(Theme newTheme) +{ + if (_theme != newTheme) { + _theme = newTheme; + + // Notify all objects of the new theme + foreach(QGCPalette* palette, _paletteObjects) { + palette->_themeChanged(); + } + } +} + +void QGCPalette::_themeChanged(void) +{ + emit paletteChanged(); +} diff --git a/src/QGCPalette.h b/src/QGCPalette.h index e07a9adfc..61b2a9ebd 100644 --- a/src/QGCPalette.h +++ b/src/QGCPalette.h @@ -22,6 +22,11 @@ ======================================================================*/ /// @file +/// @brief QGCPalette is used by QML ui to bind colors to the QGC pallete. The implementation +/// is similar to the QML SystemPalette and should be used in the same way. Refer to +/// that documentation for details. The one difference is that QGCPalette also supports +/// a light and dark theme which you can switch between. +/// /// @author Don Gagne #ifndef QGCPalette_h @@ -42,13 +47,6 @@ class QGCPalette : public QObject Q_PROPERTY(QColor base READ base NOTIFY paletteChanged) Q_PROPERTY(QColor button READ button NOTIFY paletteChanged) Q_PROPERTY(QColor buttonText READ buttonText NOTIFY paletteChanged) - Q_PROPERTY(QColor dark READ dark NOTIFY paletteChanged) - Q_PROPERTY(QColor highlight READ highlight NOTIFY paletteChanged) - Q_PROPERTY(QColor highlightedText READ highlightedText NOTIFY paletteChanged) - Q_PROPERTY(QColor light READ light NOTIFY paletteChanged) - Q_PROPERTY(QColor mid READ mid NOTIFY paletteChanged) - Q_PROPERTY(QColor midlight READ midlight NOTIFY paletteChanged) - Q_PROPERTY(QColor shadow READ shadow NOTIFY paletteChanged) Q_PROPERTY(QColor text READ text NOTIFY paletteChanged) Q_PROPERTY(QColor window READ window NOTIFY paletteChanged) Q_PROPERTY(QColor windowText READ windowText NOTIFY paletteChanged) @@ -60,50 +58,49 @@ public: Inactive }; + enum Theme { + Light = 0, + Dark + }; + QGCPalette(QObject* parent = NULL); ~QGCPalette(); ColorGroup colorGroup(void) const { return _colorGroup; } void setColorGroup(ColorGroup colorGroup); - QColor alternateBase(void) const { return _alternateBase[_colorGroup]; } - QColor base(void) const { return _base[_colorGroup]; } - QColor button(void) const { return _button[_colorGroup]; } - QColor buttonText(void) const { return _buttonText[_colorGroup]; } - QColor dark(void) const { return _dark[_colorGroup]; } - QColor highlight(void) const { return _highlight[_colorGroup]; } - QColor highlightedText(void) const { return _highlightedText[_colorGroup]; } - QColor light(void) const { return _light[_colorGroup]; } - QColor mid(void) const { return _mid[_colorGroup]; } - QColor midlight(void) const { return _midlight[_colorGroup]; } - QColor shadow(void) const { return _shadow[_colorGroup]; } - QColor text(void) const { return _text[_colorGroup]; } - QColor window(void) const { return _window[_colorGroup]; } - QColor windowText(void) const { return _windowText[_colorGroup]; } + QColor alternateBase(void) const { return _alternateBase[_theme][_colorGroup]; } + QColor base(void) const { return _base[_theme][_colorGroup]; } + QColor button(void) const { return _button[_theme][_colorGroup]; } + QColor buttonText(void) const { return _buttonText[_theme][_colorGroup]; } + QColor text(void) const { return _text[_theme][_colorGroup]; } + QColor window(void) const { return _window[_theme][_colorGroup]; } + QColor windowText(void) const { return _windowText[_theme][_colorGroup]; } + + static Theme globalTheme(void) { return _theme; } + static void setGlobalTheme(Theme newTheme); signals: void paletteChanged(void); private: - ColorGroup _colorGroup; - - static bool _paletteLoaded; + static Theme _theme; ///< There is a single theme for all palettes + ColorGroup _colorGroup; ///< Currently selected ColorGroup + static const int _cThemes = 2; static const int _cColorGroups = 3; - static QColor _alternateBase[_cColorGroups]; - static QColor _base[_cColorGroups]; - static QColor _button[_cColorGroups]; - static QColor _buttonText[_cColorGroups]; - static QColor _dark[_cColorGroups]; - static QColor _highlight[_cColorGroups]; - static QColor _highlightedText[_cColorGroups]; - static QColor _light[_cColorGroups]; - static QColor _mid[_cColorGroups]; - static QColor _midlight[_cColorGroups]; - static QColor _shadow[_cColorGroups]; - static QColor _text[_cColorGroups]; - static QColor _window[_cColorGroups]; - static QColor _windowText[_cColorGroups]; + + static QColor _alternateBase[_cThemes][_cColorGroups]; + static QColor _base[_cThemes][_cColorGroups]; + static QColor _button[_cThemes][_cColorGroups]; + static QColor _buttonText[_cThemes][_cColorGroups]; + static QColor _text[_cThemes][_cColorGroups]; + static QColor _window[_cThemes][_cColorGroups]; + static QColor _windowText[_cThemes][_cColorGroups]; + + void _themeChanged(void); + + static QList _paletteObjects; ///< List of all active QGCPalette objects }; #endif -- 2.22.0