diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index e88fd7ea9263a6e704ab88d6474e61425eb85be2..d31bcbf01783777c41715087a7f3b1a00a26f8c0 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -571,8 +571,6 @@ HEADERS += \ src/Camera/QGCCameraManager.h \ src/CmdLineOptParser.h \ src/FirmwarePlugin/PX4/px4_custom_mode.h \ - src/FlightMap/Widgets/InstrumentValue.h \ - src/FlightMap/Widgets/ValuesWidgetController.h \ src/FollowMe/FollowMe.h \ src/Joystick/Joystick.h \ src/Joystick/JoystickManager.h \ @@ -645,6 +643,8 @@ HEADERS += \ src/QmlControls/AppMessages.h \ src/QmlControls/CoordinateVector.h \ src/QmlControls/EditPositionDialogController.h \ + src/QmlControls/InstrumentValueData.h \ + src/QmlControls/InstrumentValueArea.h \ src/QmlControls/ParameterEditorController.h \ src/QmlControls/QGCFileDialogController.h \ src/QmlControls/QGCImageProvider.h \ @@ -780,8 +780,6 @@ SOURCES += \ src/Camera/QGCCameraIO.cc \ src/Camera/QGCCameraManager.cc \ src/CmdLineOptParser.cc \ - src/FlightMap/Widgets/InstrumentValue.cc \ - src/FlightMap/Widgets/ValuesWidgetController.cc \ src/FollowMe/FollowMe.cc \ src/Joystick/Joystick.cc \ src/Joystick/JoystickManager.cc \ @@ -851,6 +849,8 @@ SOURCES += \ src/QmlControls/AppMessages.cc \ src/QmlControls/CoordinateVector.cc \ src/QmlControls/EditPositionDialogController.cc \ + src/QmlControls/InstrumentValueData.cc \ + src/QmlControls/InstrumentValueArea.cc \ src/QmlControls/ParameterEditorController.cc \ src/QmlControls/QGCFileDialogController.cc \ src/QmlControls/QGCImageProvider.cc \ diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index e1ed7e03f2b7d15b14b550b43fbaa00d93a2734f..524389b63fe16847124258353452d3c7ecabe7c3 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -99,6 +99,9 @@ src/PlanView/GeoFenceEditor.qml src/PlanView/GeoFenceMapVisuals.qml src/QmlControls/IndicatorButton.qml + src/QmlControls/InstrumentValue.qml + src/QmlControls/InstrumentValueArea.qml + src/QmlControls/InstrumentValueEditDialog.qml src/QmlControls/JoystickThumbPad.qml src/QmlControls/KMLOrSHPFileDialog.qml src/QmlControls/LogReplayStatusBar.qml @@ -209,8 +212,6 @@ src/FlightMap/MapItems/CustomMapItems.qml src/FlightMap/FlightMap.qml src/FlightMap/Widgets/InstrumentSwipeView.qml - src/FlightMap/Widgets/InstrumentValue.qml - src/FlightMap/Widgets/InstrumentValueEditDialog.qml src/FlightMap/Widgets/MapFitFunctions.qml src/FlightMap/MapScale.qml src/FlightMap/MapItems/MissionItemIndicator.qml diff --git a/src/FlightMap/Widgets/InstrumentValue.cc b/src/FlightMap/Widgets/InstrumentValue.cc deleted file mode 100644 index b0324641890b07e656f094fcf2e27f73669fb3cf..0000000000000000000000000000000000000000 --- a/src/FlightMap/Widgets/InstrumentValue.cc +++ /dev/null @@ -1,510 +0,0 @@ -/**************************************************************************** - * - * (c) 2009-2020 QGROUNDCONTROL PROJECT - * - * QGroundControl is licensed according to the terms in the file - * COPYING.md in the root of the source code directory. - * - ****************************************************************************/ - - -#include "InstrumentValue.h" -#include "QGCApplication.h" -#include "QGCCorePlugin.h" - -#include - -const char* InstrumentValue::_versionKey = "version"; -const char* InstrumentValue::_factGroupNameKey = "groupName"; -const char* InstrumentValue::_factNameKey = "factName"; -const char* InstrumentValue::_textKey = "text"; -const char* InstrumentValue::_fontSizeKey = "fontSize"; -const char* InstrumentValue::_showUnitsKey = "showUnits"; -const char* InstrumentValue::_iconKey = "icon"; -const char* InstrumentValue::_labelPositionKey = "labelPosition"; -const char* InstrumentValue::_rangeTypeKey = "rangeType"; -const char* InstrumentValue::_rangeValuesKey = "rangeValues"; -const char* InstrumentValue::_rangeColorsKey = "rangeColors"; -const char* InstrumentValue::_rangeIconsKey = "rangeIcons"; -const char* InstrumentValue::_rangeOpacitiesKey = "rangeOpacities"; -const char* InstrumentValue::_vehicleFactGroupName = "Vehicle"; - -QStringList InstrumentValue::_iconNames; - -// Important: The indices of these strings must match the InstrumentValue::LabelPosition enumconst QStringList InstrumentValue::_labelPositionNames -const QStringList InstrumentValue::_labelPositionNames = { - QT_TRANSLATE_NOOP("InstrumentValue", "Above"), - QT_TRANSLATE_NOOP("InstrumentValue", "Left"), -}; - -// Important: The indices of these strings must match the InstrumentValue::FontSize enum -const QStringList InstrumentValue::_fontSizeNames = { - QT_TRANSLATE_NOOP("InstrumentValue", "Default"), - QT_TRANSLATE_NOOP("InstrumentValue", "Small"), - QT_TRANSLATE_NOOP("InstrumentValue", "Medium"), - QT_TRANSLATE_NOOP("InstrumentValue", "Large"), -}; - -// Important: The indices of these strings must match the InstrumentValue::RangeType enum -const QStringList InstrumentValue::_rangeTypeNames = { - QT_TRANSLATE_NOOP("InstrumentValue", "None"), - QT_TRANSLATE_NOOP("InstrumentValue", "Color"), - QT_TRANSLATE_NOOP("InstrumentValue", "Opacity"), - QT_TRANSLATE_NOOP("InstrumentValue", "Icon"), -}; - -InstrumentValue::InstrumentValue(Vehicle* activeVehicle, FontSize fontSize, QmlObjectListModel* rowModel) - : QObject (rowModel) - , _activeVehicle(activeVehicle) - , _rowModel (rowModel) - , _fontSize (fontSize) -{ - if (_iconNames.isEmpty()) { - QDir iconDir(":/InstrumentValueIcons/"); - _iconNames = iconDir.entryList(); - } - - activeVehicleChanged(_activeVehicle); - - connect(this, &InstrumentValue::rangeTypeChanged, this, &InstrumentValue::_resetRangeInfo); - connect(this, &InstrumentValue::rangeTypeChanged, this, &InstrumentValue::_updateRanges); - connect(this, &InstrumentValue::rangeValuesChanged, this, &InstrumentValue::_updateRanges); - connect(this, &InstrumentValue::rangeColorsChanged, this, &InstrumentValue::_updateRanges); - connect(this, &InstrumentValue::rangeOpacitiesChanged, this, &InstrumentValue::_updateRanges); - connect(this, &InstrumentValue::rangeIconsChanged, this, &InstrumentValue::_updateRanges); -} - -void InstrumentValue::activeVehicleChanged(Vehicle* activeVehicle) -{ - if (_fact) { - disconnect(_fact, &Fact::rawValueChanged, this, &InstrumentValue::_updateColor); - } - - _activeVehicle = activeVehicle; - - _factGroupNames.clear(); - _factGroupNames = _activeVehicle->factGroupNames(); - for (QString& name: _factGroupNames) { - name[0] = name[0].toUpper(); - } - _factGroupNames.prepend(_vehicleFactGroupName); - emit factGroupNamesChanged(_factGroupNames); - - if (_fact) { - _fact = nullptr; - - FactGroup* factGroup = nullptr; - if (_factGroupName == _vehicleFactGroupName) { - factGroup = _activeVehicle; - } else { - factGroup = _activeVehicle->getFactGroup(_factGroupName); - } - - if (factGroup) { - _fact = factGroup->getFact(_factName); - } - emit factChanged(_fact); - - connect(_fact, &Fact::rawValueChanged, this, &InstrumentValue::_updateRanges); - } - - _updateRanges(); -} - -void InstrumentValue::setFact(const QString& factGroupName, const QString& factName) -{ - if (_fact) { - disconnect(_fact, &Fact::rawValueChanged, this, &InstrumentValue::_updateRanges); - _fact = nullptr; - } - - FactGroup* factGroup = nullptr; - if (factGroupName == _vehicleFactGroupName) { - factGroup = _activeVehicle; - } else { - factGroup = _activeVehicle->getFactGroup(factGroupName); - } - - _factValueNames.clear(); - _factValueNames = factGroup->factNames(); - for (QString& name: _factValueNames) { - name[0] = name[0].toUpper(); - } - - QString nonEmptyFactName; - if (factGroup) { - if (factName.isEmpty()) { - nonEmptyFactName = _factValueNames[0]; - } else { - nonEmptyFactName = factName; - } - _fact = factGroup->getFact(nonEmptyFactName); - } - - if (_fact) { - _factGroupName = factGroupName; - _factName = nonEmptyFactName; - - connect(_fact, &Fact::rawValueChanged, this, &InstrumentValue::_updateRanges); - } else { - _factName.clear(); - _factGroupName.clear(); - } - - emit factChanged (_fact); - emit factNameChanged (_factName); - emit factGroupNameChanged (_factGroupName); - emit factValueNamesChanged (_factValueNames); - - _updateRanges(); -} - -void InstrumentValue::_setFontSize(FontSize fontSize) -{ - if (fontSize != _fontSize) { - _fontSize = fontSize; - emit fontSizeChanged(fontSize); - } -} - -void InstrumentValue::setFontSize(FontSize fontSize) -{ - _setFontSize(fontSize); - - // All other items in row must change to match - for (int i=0; i<_rowModel->count(); i++) { - InstrumentValue* instrumentValue = _rowModel->value(i); - if (instrumentValue != this) { - instrumentValue->_setFontSize(fontSize); - } - } -} - -void InstrumentValue::saveToSettings(QSettings& settings) const -{ - settings.setValue(_versionKey, 1); - settings.setValue(_textKey, _text); - settings.setValue(_fontSizeKey, _fontSize); - settings.setValue(_showUnitsKey, _showUnits); - settings.setValue(_iconKey, _icon); - settings.setValue(_labelPositionKey, _labelPosition); - settings.setValue(_rangeTypeKey, _rangeType); - - if (_rangeType != NoRangeInfo) { - settings.setValue(_rangeValuesKey, _rangeValues); - } - - switch (_rangeType) { - case NoRangeInfo: - break; - case ColorRange: - settings.setValue(_rangeColorsKey, _rangeColors); - break; - case OpacityRange: - settings.setValue(_rangeOpacitiesKey, _rangeOpacities); - break; - case IconSelectRange: - settings.setValue(_rangeIconsKey, _rangeIcons); - break; - } - - if (_fact) { - settings.setValue(_factGroupNameKey, _factGroupName); - settings.setValue(_factNameKey, _factName); - } else { - settings.setValue(_factGroupNameKey, ""); - settings.setValue(_factNameKey, ""); - } -} - -void InstrumentValue::readFromSettings(const QSettings& settings) -{ - _factGroupName = settings.value(_factGroupNameKey, QString()).toString(); - _text = settings.value(_textKey, QString()).toString(); - _fontSize = settings.value(_fontSizeKey, DefaultFontSize).value(); - _showUnits = settings.value(_showUnitsKey, true).toBool(); - _icon = settings.value(_iconKey, QString()).toString(); - _labelPosition = settings.value(_labelPositionKey, LabelLeft).value(); - _rangeType = settings.value(_rangeTypeKey, NoRangeInfo).value(); - - // Do this now, since the signal will cause _resetRangeInfo to be called trashing values - emit rangeTypeChanged(_rangeType); - - _rangeValues.clear(); - _rangeColors.clear(); - _rangeOpacities.clear(); - _rangeIcons.clear(); - if (_rangeType != NoRangeInfo) { - _rangeValues = settings.value(_rangeValuesKey).value(); - } - switch (_rangeType) { - case NoRangeInfo: - break; - case ColorRange: - _rangeColors = settings.value(_rangeColorsKey).value(); - break; - case OpacityRange: - _rangeOpacities = settings.value(_rangeOpacitiesKey).value(); - break; - case IconSelectRange: - _rangeIcons = settings.value(_rangeIconsKey).value(); - break; - } - - QString factName = settings.value(_factNameKey).toString(); - if (!factName.isEmpty()) { - setFact(_factGroupName, factName); - } - - emit factChanged (_fact); - emit factGroupNameChanged (_factGroupName); - emit textChanged (_text); - emit fontSizeChanged (_fontSize); - emit showUnitsChanged (_showUnits); - emit iconChanged (_icon); - emit labelPositionChanged (_labelPosition); - emit rangeValuesChanged (_rangeValues); - emit rangeColorsChanged (_rangeColors); - emit rangeOpacitiesChanged (_rangeOpacities); - emit rangeIconsChanged (_rangeIcons); -} - -void InstrumentValue::setText(const QString& text) -{ - if (text != _text) { - _text = text; - emit textChanged(text); - } -} - -void InstrumentValue::setShowUnits(bool showUnits) -{ - if (showUnits != _showUnits) { - _showUnits = showUnits; - emit showUnitsChanged(showUnits); - } -} - -void InstrumentValue::clearFact(void) -{ - _fact = nullptr; - _factGroupName.clear(); - _text.clear(); - _icon.clear(); - _showUnits = true; - - emit factChanged (_fact); - emit factGroupNameChanged (_factGroupName); - emit textChanged (_text); - emit iconChanged (_icon); - emit showUnitsChanged (_showUnits); -} - -void InstrumentValue::setIcon(const QString& icon) -{ - if (icon != _icon) { - _icon = icon; - emit iconChanged(_icon); - } -} - -void InstrumentValue::setLabelPosition(LabelPosition labelPosition) -{ - if (labelPosition != _labelPosition) { - _labelPosition = labelPosition; - emit labelPositionChanged(labelPosition); - } -} - -void InstrumentValue::setRangeType(RangeType rangeType) -{ - if (rangeType != _rangeType) { - _rangeType = rangeType; - emit rangeTypeChanged(rangeType); - } -} - -void InstrumentValue::setRangeValues(const QVariantList& rangeValues) -{ - _rangeValues = rangeValues; - emit rangeValuesChanged(rangeValues); -} - -void InstrumentValue::setRangeColors (const QVariantList& rangeColors) -{ - _rangeColors = rangeColors; - emit rangeColorsChanged(rangeColors); -} - -void InstrumentValue::setRangeIcons(const QVariantList& rangeIcons) -{ - _rangeIcons = rangeIcons; - emit rangeIconsChanged(rangeIcons); -} - -void InstrumentValue::setRangeOpacities(const QVariantList& rangeOpacities) -{ - _rangeOpacities = rangeOpacities; - emit rangeOpacitiesChanged(rangeOpacities); -} - -void InstrumentValue::_resetRangeInfo(void) -{ - _rangeValues.clear(); - _rangeColors.clear(); - _rangeOpacities.clear(); - _rangeIcons.clear(); - - if (_rangeType != NoRangeInfo) { - _rangeValues = { 0.0, 100.0 }; - } - for (int i=0; i<_rangeValues.count() + 1; i++) { - switch (_rangeType) { - case NoRangeInfo: - break; - case ColorRange: - _rangeColors.append(QColor("green")); - break; - case OpacityRange: - _rangeOpacities.append(1.0); - break; - case IconSelectRange: - _rangeIcons.append(_iconNames[0]); - break; - } - } - - emit rangeValuesChanged (_rangeValues); - emit rangeColorsChanged (_rangeColors); - emit rangeOpacitiesChanged (_rangeOpacities); - emit rangeIconsChanged (_rangeIcons); -} - -void InstrumentValue::addRangeValue(void) -{ - _rangeValues.append(_rangeValues.last().toDouble() + 1); - - switch (_rangeType) { - case NoRangeInfo: - break; - case ColorRange: - _rangeColors.append(QColor("green")); - break; - case OpacityRange: - _rangeOpacities.append(1.0); - break; - case IconSelectRange: - _rangeIcons.append(_iconNames[0]); - break; - } - - emit rangeValuesChanged (_rangeValues); - emit rangeColorsChanged (_rangeColors); - emit rangeOpacitiesChanged (_rangeOpacities); - emit rangeIconsChanged (_rangeIcons); -} - -void InstrumentValue::removeRangeValue(int index) -{ - if (_rangeValues.count() < 2 || index <0 || index >= _rangeValues.count()) { - return; - } - - _rangeValues.removeAt(index); - - switch (_rangeType) { - case NoRangeInfo: - break; - case ColorRange: - _rangeColors.removeAt(index + 1); - break; - case OpacityRange: - _rangeOpacities.removeAt(index + 1); - break; - case IconSelectRange: - _rangeIcons.removeAt(index + 1); - break; - } - - emit rangeValuesChanged (_rangeValues); - emit rangeColorsChanged (_rangeColors); - emit rangeOpacitiesChanged (_rangeOpacities); - emit rangeIconsChanged (_rangeIcons); -} - -void InstrumentValue::_updateRanges(void) -{ - _updateColor(); - _updateIcon(); - _updateOpacity(); -} - -void InstrumentValue::_updateColor(void) -{ - QColor newColor; - - int rangeIndex = -1; - - if (_rangeType == ColorRange && _fact) { - rangeIndex =_currentRangeIndex(_fact->rawValue().toDouble()); - } - if (rangeIndex != -1) { - newColor = _rangeColors[rangeIndex].value(); - } - - if (newColor != _currentColor) { - _currentColor = newColor; - emit currentColorChanged(_currentColor); - } -} - -void InstrumentValue::_updateOpacity(void) -{ - double newOpacity = 1.0; - - int rangeIndex = -1; - - if (_rangeType == OpacityRange && _fact) { - rangeIndex =_currentRangeIndex(_fact->rawValue().toDouble()); - } - if (rangeIndex != -1) { - newOpacity = _rangeOpacities[rangeIndex].toDouble(); - } - - if (!qFuzzyCompare(newOpacity, _currentOpacity)) { - _currentOpacity = newOpacity; - emit currentOpacityChanged(newOpacity); - } -} - -void InstrumentValue::_updateIcon(void) -{ - QString newIcon; - - int rangeIndex = -1; - - if (_rangeType == IconSelectRange && _fact) { - rangeIndex =_currentRangeIndex(_fact->rawValue().toDouble()); - } - if (rangeIndex != -1) { - newIcon = _rangeIcons[rangeIndex].toString(); - } - - if (newIcon != _currentIcon) { - _currentIcon = newIcon; - emit currentIconChanged(newIcon); - } -} - -int InstrumentValue::_currentRangeIndex(const QVariant& value) -{ - if (qIsNaN(value.toDouble())) { - return 0; - } - for (int i=0; i<_rangeValues.count(); i++) { - if (value.toDouble() <= _rangeValues[i].toDouble()) { - return i; - } - } - return _rangeValues.count(); -} diff --git a/src/FlightMap/Widgets/InstrumentValue.h b/src/FlightMap/Widgets/InstrumentValue.h deleted file mode 100644 index 2c40dd3de146a33ff5c3a72aa305964fc1c3fbb6..0000000000000000000000000000000000000000 --- a/src/FlightMap/Widgets/InstrumentValue.h +++ /dev/null @@ -1,187 +0,0 @@ -/**************************************************************************** - * - * (c) 2009-2020 QGROUNDCONTROL PROJECT - * - * QGroundControl is licensed according to the terms in the file - * COPYING.md in the root of the source code directory. - * - ****************************************************************************/ - -#pragma once - -#include "FactSystem.h" -#include "QmlObjectListModel.h" -#include "QGCApplication.h" - -#include - -class InstrumentValue : public QObject -{ - Q_OBJECT - -public: - enum FontSize { - DefaultFontSize=0, - SmallFontSize, - MediumFontSize, - LargeFontSize, - }; - Q_ENUMS(FontSize) - - enum LabelPosition { - LabelAbove = 0, - LabelLeft, - }; - Q_ENUMS(LabelPosition) - - enum RangeType { - NoRangeInfo = 0, - ColorRange, - OpacityRange, - IconSelectRange, - }; - Q_ENUMS(RangeType) - - InstrumentValue(Vehicle* activeVehicle, FontSize fontSize, QmlObjectListModel* rowModel); - - Q_PROPERTY(QStringList factGroupNames MEMBER _factGroupNames NOTIFY factGroupNamesChanged) - Q_PROPERTY(QStringList factValueNames MEMBER _factValueNames NOTIFY factValueNamesChanged) - Q_PROPERTY(QString factGroupName MEMBER _factGroupName NOTIFY factGroupNameChanged) - Q_PROPERTY(QString factName MEMBER _factName NOTIFY factNameChanged) - Q_PROPERTY(Fact* fact READ fact NOTIFY factChanged) - Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged) - Q_PROPERTY(QString icon READ icon WRITE setIcon NOTIFY iconChanged) ///< If !isEmpty icon will be show instead of label - Q_PROPERTY(LabelPosition labelPosition READ labelPosition WRITE setLabelPosition NOTIFY labelPositionChanged) - Q_PROPERTY(QStringList labelPositionNames MEMBER _labelPositionNames CONSTANT) - Q_PROPERTY(QStringList iconNames MEMBER _iconNames CONSTANT) - Q_PROPERTY(FontSize fontSize READ fontSize WRITE setFontSize NOTIFY fontSizeChanged) - Q_PROPERTY(QStringList fontSizeNames MEMBER _fontSizeNames CONSTANT) - Q_PROPERTY(bool showUnits READ showUnits WRITE setShowUnits NOTIFY showUnitsChanged) - Q_PROPERTY(QStringList rangeTypeNames MEMBER _rangeTypeNames CONSTANT) - Q_PROPERTY(RangeType rangeType READ rangeType WRITE setRangeType NOTIFY rangeTypeChanged) - Q_PROPERTY(QVariantList rangeValues READ rangeValues WRITE setRangeValues NOTIFY rangeValuesChanged) - Q_PROPERTY(QVariantList rangeColors READ rangeColors WRITE setRangeColors NOTIFY rangeColorsChanged) - Q_PROPERTY(QVariantList rangeIcons READ rangeIcons WRITE setRangeIcons NOTIFY rangeIconsChanged) - Q_PROPERTY(QVariantList rangeOpacities READ rangeOpacities WRITE setRangeOpacities NOTIFY rangeOpacitiesChanged) - Q_PROPERTY(QColor currentColor MEMBER _currentColor NOTIFY currentColorChanged) - Q_PROPERTY(double currentOpacity MEMBER _currentOpacity NOTIFY currentOpacityChanged) - Q_PROPERTY(QString currentIcon MEMBER _currentIcon NOTIFY currentIconChanged) - - Q_INVOKABLE void setFact (const QString& factGroupName, const QString& factName); - Q_INVOKABLE void clearFact (void); - Q_INVOKABLE bool isValidColor (const QColor& color) { return color.isValid(); } - Q_INVOKABLE QColor invalidColor (void) { return QColor(); } - Q_INVOKABLE void addRangeValue (void); - Q_INVOKABLE void removeRangeValue(int index); - - Fact* fact (void) { return _fact; } - FontSize fontSize (void) const { return _fontSize; } - QString text (void) const { return _text; } - bool showUnits (void) const { return _showUnits; } - QString icon (void) const { return _icon; } - LabelPosition labelPosition (void) const { return _labelPosition; } - RangeType rangeType (void) const { return _rangeType; } - QVariantList rangeValues (void) const { return _rangeValues; } - QVariantList rangeColors (void) const { return _rangeColors; } - QVariantList rangeIcons (void) const { return _rangeIcons; } - QVariantList rangeOpacities (void) const { return _rangeOpacities; } - void setFontSize (FontSize fontSize); - void setText (const QString& text); - void setShowUnits (bool showUnits); - void setIcon (const QString& icon); - void setLabelPosition (LabelPosition labelPosition); - void setRangeType (RangeType rangeType); - void setRangeValues (const QVariantList& rangeValues); - void setRangeColors (const QVariantList& rangeColors); - void setRangeIcons (const QVariantList& rangeIcons); - void setRangeOpacities (const QVariantList& rangeOpacities); - void activeVehicleChanged (Vehicle* activeVehicle); - void saveToSettings (QSettings& settings) const; - void readFromSettings (const QSettings& settings); - -signals: - void factChanged (Fact* fact); - void factNameChanged (const QString& factName); - void factGroupNameChanged (const QString& factGroup); - void textChanged (QString text); - void fontSizeChanged (FontSize fontSize); - void showUnitsChanged (bool showUnits); - void iconChanged (const QString& icon); - void labelPositionChanged (LabelPosition labelPosition); - void factGroupNamesChanged (const QStringList& factGroupNames); - void factValueNamesChanged (const QStringList& factValueNames); - void rangeTypeChanged (RangeType rangeType); - void rangeValuesChanged (const QVariantList& rangeValues); - void rangeColorsChanged (const QVariantList& rangeColors); - void rangeIconsChanged (const QVariantList& rangeIcons); - void rangeOpacitiesChanged (const QVariantList& rangeOpacities); - void currentColorChanged (const QColor& currentColor); - void currentOpacityChanged (double currentOpacity); - void currentIconChanged (const QString& currentIcon); - -private slots: - void _resetRangeInfo (void); - void _updateRanges (void); - -private: - void _setFontSize (FontSize fontSize); - int _currentRangeIndex (const QVariant& value); - void _updateColor (void); - void _updateIcon (void); - void _updateOpacity (void); - - Vehicle* _activeVehicle = nullptr; - QmlObjectListModel* _rowModel = nullptr; - Fact* _fact = nullptr; - QString _factName; - QString _factGroupName; - QString _text; - bool _showUnits = true; - FontSize _fontSize = DefaultFontSize; - QString _icon; - LabelPosition _labelPosition = LabelLeft; - QStringList _factGroupNames; - QStringList _factValueNames; - QColor _currentColor; - double _currentOpacity = 1.0; - QString _currentIcon; - - // Ranges allow you to specifiy semantics to apply when a value is within a certain range. - // The limits for each section of the range are specified in _rangeValues. With the first - // element indicating a range from that value to -infinity and the last element indicating - // a range from the value to +infinity. - // - // The semantics to apply are defined by the _rangeType value. With the semantic lists having - // a specific value for each section of the range. There should be _rangeValues.count() + 2 - // semantic values in the apppropriate list. - RangeType _rangeType = NoRangeInfo; - QVariantList _rangeValues; ///< double values which indicate range setpoints - QVariantList _rangeColors; ///< QColor - QVariantList _rangeIcons; ///< QString resource name - QVariantList _rangeOpacities; /// double opacity value - - // These are user facing string for the various enums. - static const QStringList _rangeTypeNames; - static const QStringList _labelPositionNames; - static QStringList _iconNames; - static const QStringList _fontSizeNames; - - static const char* _versionKey; - static const char* _factGroupNameKey; - static const char* _factNameKey; - static const char* _textKey; - static const char* _fontSizeKey; - static const char* _showUnitsKey; - static const char* _iconKey; - static const char* _labelPositionKey; - static const char* _rangeTypeKey; - static const char* _rangeValuesKey; - static const char* _rangeColorsKey; - static const char* _rangeIconsKey; - static const char* _rangeOpacitiesKey; - static const char* _vehicleFactGroupName; -}; - -Q_DECLARE_METATYPE(InstrumentValue::FontSize) -Q_DECLARE_METATYPE(InstrumentValue::LabelPosition) -Q_DECLARE_METATYPE(InstrumentValue::RangeType) diff --git a/src/FlightMap/Widgets/ValuePageWidget.qml b/src/FlightMap/Widgets/ValuePageWidget.qml index 31fd20cc6bf917f8578d3ad78d88b7cede5ed470..14e2d0eb8ccba48bd7be85b7c611bc4cd93bbea6 100644 --- a/src/FlightMap/Widgets/ValuePageWidget.qml +++ b/src/FlightMap/Widgets/ValuePageWidget.qml @@ -23,157 +23,17 @@ import QGroundControl.FlightMap 1.0 import QGroundControl 1.0 /// Value page for InstrumentPanel PageView -Column { - id: _root - width: pageWidth - spacing: ScreenTools.defaultFontPixelHeight / 2 +InstrumentValueArea { + id: _root + width: pageWidth + userSettingsGroup: valuePageUserSettingsGroup + defaultSettingsGroup: valuePageDefaultSettingsGroup + orientation: InstrumentValueArea.VerticalOrientation property bool showSettingsIcon: true property bool showLockIcon: true - property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle ? QGroundControl.multiVehicleManager.activeVehicle : QGroundControl.multiVehicleManager.offlineEditingVehicle - property real _margins: ScreenTools.defaultFontPixelWidth / 2 - property int _colMax: 4 - property bool _settingsUnlocked: false - property var instrumentValue: null - property real _columnButtonWidth: ScreenTools.minTouchPixels / 2 - property real _columnButtonHeight: ScreenTools.minTouchPixels - property real _columnButtonSpacing: 2 - property real _columnButtonsTotalHeight: (_columnButtonHeight * 2) + _columnButtonSpacing - - QGCPalette { id:qgcPal; colorGroupEnabled: true } - QGCPalette { id:qgcPalDisabled; colorGroupEnabled: false } - - ValuesWidgetController { id: controller } - function showSettings(settingsUnlocked) { - _settingsUnlocked = settingsUnlocked - } - - function listContains(list, value) { - for (var i=0; i - * - * QGroundControl is licensed according to the terms in the file - * COPYING.md in the root of the source code directory. - * - ****************************************************************************/ - -#include "ValuesWidgetController.h" -#include "QGCApplication.h" -#include "QGCCorePlugin.h" - -#include - -const char* ValuesWidgetController::_groupKey = "ValuesWidget2"; -const char* ValuesWidgetController::_rowsKey = "rows"; -const char* ValuesWidgetController::_columnsKey = "columns"; - -const char* ValuesWidgetController::_deprecatedGroupKey = "ValuesWidget"; -const char* ValuesWidgetController::_deprecatedLargeValuesKey = "large"; -const char* ValuesWidgetController::_deprecatedSmallValuesKey = "small"; - -ValuesWidgetController::ValuesWidgetController(bool forDefaultSettingsCreation) - : _valuesModel(new QmlObjectListModel(this)) -{ - QSettings settings; - - settings.beginGroup(_groupKey); - - _multiVehicleMgr = qgcApp()->toolbox()->multiVehicleManager(); - connect(_multiVehicleMgr, &MultiVehicleManager::activeVehicleChanged, this, &ValuesWidgetController::_activeVehicleChanged); - - if (!forDefaultSettingsCreation) { - _loadSettings(); - } -} - -void ValuesWidgetController::_connectSignalsToController(InstrumentValue* value, ValuesWidgetController* controller) -{ - connect(value, &InstrumentValue::factNameChanged, controller, &ValuesWidgetController::_saveSettings); - connect(value, &InstrumentValue::factGroupNameChanged, controller, &ValuesWidgetController::_saveSettings); - connect(value, &InstrumentValue::textChanged, controller, &ValuesWidgetController::_saveSettings); - connect(value, &InstrumentValue::fontSizeChanged, controller, &ValuesWidgetController::_saveSettings); - connect(value, &InstrumentValue::showUnitsChanged, controller, &ValuesWidgetController::_saveSettings); - connect(value, &InstrumentValue::iconChanged, controller, &ValuesWidgetController::_saveSettings); - connect(value, &InstrumentValue::labelPositionChanged, controller, &ValuesWidgetController::_saveSettings); - connect(value, &InstrumentValue::rangeTypeChanged, controller, &ValuesWidgetController::_saveSettings); - connect(value, &InstrumentValue::rangeValuesChanged, controller, &ValuesWidgetController::_saveSettings); - connect(value, &InstrumentValue::rangeColorsChanged, controller, &ValuesWidgetController::_saveSettings); - connect(value, &InstrumentValue::rangeOpacitiesChanged, controller, &ValuesWidgetController::_saveSettings); - connect(value, &InstrumentValue::rangeIconsChanged, controller, &ValuesWidgetController::_saveSettings); -} - -InstrumentValue* ValuesWidgetController::_createNewInstrumentValueWorker(Vehicle* activeVehicle, InstrumentValue::FontSize fontSize, QmlObjectListModel* rowModel) -{ - InstrumentValue* newValue = new InstrumentValue(activeVehicle, fontSize, rowModel); - _connectSignalsToController(newValue, this); - return newValue; -} - -InstrumentValue* ValuesWidgetController::appendColumn(int rowIndex) -{ - InstrumentValue* newValue = nullptr; - - if (rowIndex >= 0 && rowIndex < _valuesModel->count()) { - QmlObjectListModel* row = _valuesModel->value(rowIndex); - InstrumentValue::FontSize fontSize = InstrumentValue::DefaultFontSize; - if (row->count()) { - fontSize = row->value(0)->fontSize(); - } - newValue = _createNewInstrumentValueWorker(_currentActiveVehicle(), fontSize, row); - row->append(newValue); - } - _saveSettings(); - - return newValue; -} - -void ValuesWidgetController::deleteLastColumn(int rowIndex) -{ - if (rowIndex >= 0 && rowIndex < _valuesModel->count()) { - QmlObjectListModel* row = _valuesModel->value(rowIndex); - - if (rowIndex != 0 || row->count() > 1) { - row->removeAt(row->count() - 1); - } - if (row->count() == 0) { - // Last column was deleted, delete the row as well - _valuesModel->removeAt(rowIndex); - } - } - _saveSettings(); -} - -QmlObjectListModel* ValuesWidgetController::appendRow(bool addBlanksColumn) -{ - QmlObjectListModel* newRow = new QmlObjectListModel(_valuesModel); - _valuesModel->append(newRow); - int rowIndex = _valuesModel->count() - 1; - if (addBlanksColumn) { - appendColumn(rowIndex); - } - _saveSettings(); - return newRow; -} - -QmlObjectListModel* ValuesWidgetController::insertRow(int atIndex, bool addBlanksColumn) -{ - QmlObjectListModel* newRow = nullptr; - - if (atIndex >= 0 && atIndex < _valuesModel->count() + 1) { - QmlObjectListModel* newRow = new QmlObjectListModel(_valuesModel); - _valuesModel->insert(atIndex, newRow); - if (addBlanksColumn) { - appendColumn(atIndex); - } - _saveSettings(); - } - return newRow; -} - -void ValuesWidgetController::deleteRow(int rowIndex) -{ - if (rowIndex >= 0 && rowIndex < _valuesModel->count()) { - if (_valuesModel->count() > 1) { - _valuesModel->removeAt(rowIndex); - } - _saveSettings(); - } -} - -Vehicle* ValuesWidgetController::_currentActiveVehicle(void) -{ - Vehicle* activeVehicle = _multiVehicleMgr->activeVehicle(); - if (!activeVehicle) { - activeVehicle = _multiVehicleMgr->offlineEditingVehicle(); - } - return activeVehicle; -} - -void ValuesWidgetController::_activeVehicleChanged(Vehicle* activeVehicle) -{ - if (!activeVehicle) { - activeVehicle = _currentActiveVehicle(); - } - - for (int rowIndex=0; rowIndex<_valuesModel->count(); rowIndex++) { - QmlObjectListModel* rowModel = _valuesModel->value(rowIndex); - for (int colIndex=0; colIndexcount(); colIndex++) { - rowModel->value(colIndex)->activeVehicleChanged(activeVehicle); - } - } -} - -bool ValuesWidgetController::_validRowIndex(int rowIndex) -{ - return rowIndex >= 0 && rowIndex < _valuesModel->count(); -} - - -int ValuesWidgetController::fontSizeForRow(int rowIndex) -{ - return _validRowIndex(rowIndex) ? _rgFontSizeByRow[rowIndex].toInt() : _rgFontSizeByRow[0].toInt(); -} - -void ValuesWidgetController::setFontSizeForRow(int rowIndex, int fontSize) -{ - if (_validRowIndex(rowIndex)) { - _rgFontSizeByRow[rowIndex] = fontSize; - } -} - -void ValuesWidgetController::_saveSettings(void) -{ - if (_preventSaveSettings) { - return; - } - - QSettings settings; - - settings.beginGroup(_groupKey); - settings.remove(QStringLiteral("")); - settings.beginWriteArray(_rowsKey); - - for (int rowIndex=0; rowIndex<_valuesModel->count(); rowIndex++) { - QmlObjectListModel* colValuesModel = _valuesModel->value(rowIndex); - - settings.setArrayIndex(rowIndex); - settings.beginWriteArray(_columnsKey); - - for (int colIndex=0; colIndexcount(); colIndex++) { - settings.setArrayIndex(colIndex); - colValuesModel->value(colIndex)->saveToSettings(settings); - } - - settings.endArray(); - } - - settings.endArray(); -} - - -void ValuesWidgetController::_loadSettings(void) -{ - QSettings settings; - - _valuesModel->deleteLater(); - _valuesModel = new QmlObjectListModel(this); - emit valuesModelChanged(_valuesModel); - - if (settings.childGroups().contains(_deprecatedGroupKey)) { - settings.beginGroup(_deprecatedGroupKey); - - QStringList largeValues = settings.value(_deprecatedLargeValuesKey).toStringList(); - QStringList smallValues = settings.value(_deprecatedSmallValuesKey).toStringList(); - QStringList altitudeProperties = { "AltitudeRelative" , "AltitudeAMSL" }; - - int rowIndex = -1; - int valueCount = 0; - QmlObjectListModel* rowModel = nullptr; - for (const QString& largeValue: largeValues) { - QStringList parts = largeValue.split("."); - QString factGroupName = _pascalCase(parts[0]); - QString factName = _pascalCase(parts[1]); - - rowModel = appendRow(false /* addBlankColumn */); - rowIndex++; - - InstrumentValue* colValue = appendColumn(rowIndex); - colValue->setFact(factGroupName, factName); - colValue->setText(colValue->fact()->shortDescription()); - colValue->setShowUnits(true); - colValue->setFontSize(altitudeProperties.contains(factName) ? InstrumentValue::LargeFontSize : InstrumentValue::DefaultFontSize); - } - - valueCount = 0; - rowModel = nullptr; - for (const QString& smallValue: smallValues) { - QStringList parts = smallValue.split("."); - QString factGroupName = _pascalCase(parts[0]); - QString factName = _pascalCase(parts[1]); - - if (!(valueCount++ & 1)) { - rowModel = appendRow(false /* addBlankColumn */); - rowIndex++; - } - - InstrumentValue* colValue = appendColumn(rowIndex); - colValue->setFact(factGroupName, factName); - colValue->setText(colValue->fact()->shortDescription()); - colValue->setShowUnits(true); - colValue->setFontSize(InstrumentValue::SmallFontSize); - } - - settings.endGroup(); - settings.remove(_deprecatedGroupKey); - } else { - _preventSaveSettings = true; - - settings.beginGroup(_groupKey); - int cRows = settings.beginReadArray(_rowsKey); - - for (int rowIndex=0; rowIndexreadFromSettings(settings); - } - - settings.endArray(); - } - - settings.endArray(); - - _preventSaveSettings = false; - } - - // Use defaults if nothing there - if (_valuesModel->count() == 0) { - _valuesModel->deleteLater(); - _valuesModel = qgcApp()->toolbox()->corePlugin()->valuesWidgetDefaultSettings(this); - emit valuesModelChanged(_valuesModel); - } -} - -void ValuesWidgetController::resetToDefaults(void) -{ - QSettings settings; - - settings.beginGroup(_groupKey); - settings.remove(""); - - _loadSettings(); -} - -void ValuesWidgetController::setPreventSaveSettings(bool preventSaveSettings) -{ - _preventSaveSettings = preventSaveSettings; -} - -void ValuesWidgetController::setValuesModelParentController(ValuesWidgetController* newParentController) -{ - _valuesModel->setParent(newParentController); - - // Signalling must be reconnected to new controller as well - for (int rowIndex=0; rowIndex<_valuesModel->count(); rowIndex++) { - QmlObjectListModel* rowModel = _valuesModel->value(rowIndex); - for (int colIndex=0; colIndexcount(); colIndex++) { - _connectSignalsToController(rowModel->value(colIndex), newParentController); - } - } -} - -QString ValuesWidgetController::_pascalCase(const QString& text) -{ - return text[0].toUpper() + text.right(text.length() - 1); -} diff --git a/src/FlightMap/Widgets/ValuesWidgetController.h b/src/FlightMap/Widgets/ValuesWidgetController.h deleted file mode 100644 index 2965e554182f63726c2518f2955ca05129ddf304..0000000000000000000000000000000000000000 --- a/src/FlightMap/Widgets/ValuesWidgetController.h +++ /dev/null @@ -1,73 +0,0 @@ -/**************************************************************************** - * - * (c) 2009-2020 QGROUNDCONTROL PROJECT - * - * QGroundControl is licensed according to the terms in the file - * COPYING.md in the root of the source code directory. - * - ****************************************************************************/ - -#pragma once - -#include "FactSystem.h" -#include "QmlObjectListModel.h" -#include "QGCApplication.h" -#include "InstrumentValue.h" - -#include - -class ValuesWidgetController : public QObject -{ - Q_OBJECT - -public: - ValuesWidgetController(bool forDefaultSettingsCreation = false); - - Q_PROPERTY(QmlObjectListModel* valuesModel READ valuesModel NOTIFY valuesModelChanged) - - Q_INVOKABLE InstrumentValue* appendColumn (int rowIndex); - Q_INVOKABLE void deleteLastColumn (int rowIndex); - Q_INVOKABLE QmlObjectListModel* appendRow (bool addBlanksColumn = true); - Q_INVOKABLE QmlObjectListModel* insertRow (int atIndex, bool addBlanksColumn = true); - Q_INVOKABLE void deleteRow (int rowIndex); - Q_INVOKABLE int fontSizeForRow (int rowIndex); - Q_INVOKABLE void setFontSizeForRow (int rowIndex, int fontSize); - Q_INVOKABLE void resetToDefaults (void); - - QmlObjectListModel* valuesModel(void) { return _valuesModel; } - - /// Turn on/off saving changes to QSettings - void setPreventSaveSettings(bool preventSaveSettings); - - /// Allows the ownership of the _valuesModel to be re-parented to a different controller - void setValuesModelParentController(ValuesWidgetController* newParentController); - -signals: - void valuesModelChanged(QmlObjectListModel* valuesModel); - -private slots: - void _activeVehicleChanged(Vehicle* activeVehicle); - Vehicle* _currentActiveVehicle(void); - void _saveSettings (void); - -private: - bool _validRowIndex (int rowIndex); - InstrumentValue* _createNewInstrumentValueWorker (Vehicle* activeVehicle, InstrumentValue::FontSize fontSize, QmlObjectListModel* rowModel); - void _loadSettings (void); - void _connectSignalsToController (InstrumentValue* value, ValuesWidgetController* controller); - QString _pascalCase (const QString& text); - - MultiVehicleManager* _multiVehicleMgr = nullptr; - QmlObjectListModel* _valuesModel = nullptr; - QVariantList _rgFontSizeByRow; - bool _preventSaveSettings = false; - - static const char* _groupKey; - static const char* _rowsKey; - static const char* _columnsKey; - - static const char* _deprecatedGroupKey; - static const char* _deprecatedLargeValuesKey; - static const char* _deprecatedSmallValuesKey; - -}; diff --git a/src/QGCApplication.cc b/src/QGCApplication.cc index 50481d9097b166030fa7a32d034f153107315334..a8265d407810cffdd0129240b1d6fcef204080c4 100644 --- a/src/QGCApplication.cc +++ b/src/QGCApplication.cc @@ -77,7 +77,8 @@ #if defined(QGC_ENABLE_MAVLINK_INSPECTOR) #include "MAVLinkInspectorController.h" #endif -#include "ValuesWidgetController.h" +#include "InstrumentValueArea.h" +#include "InstrumentValueData.h" #include "AppMessages.h" #include "SimulatedPosition.h" #include "PositionManager.h" @@ -101,7 +102,6 @@ #include "LogReplayLink.h" #include "VehicleObjectAvoidance.h" #include "TrajectoryPoints.h" -#include "ValuesWidgetController.h" #include "RCToParamDialogController.h" #include "QGCImageProvider.h" @@ -483,6 +483,7 @@ void QGCApplication::_initCommon() static const char* kQGroundControl = "QGroundControl"; static const char* kQGCControllers = "QGroundControl.Controllers"; static const char* kQGCVehicle = "QGroundControl.Vehicle"; + static const char* kQGCTemplates = "QGroundControl.Templates"; QSettings settings; @@ -510,6 +511,7 @@ void QGCApplication::_initCommon() qmlRegisterUncreatableType (kQGroundControl, 1, 0, "MissionCommandTree", kRefOnly); qmlRegisterUncreatableType (kQGroundControl, 1, 0, "CameraCalc", kRefOnly); qmlRegisterUncreatableType (kQGroundControl, 1, 0, "LogReplayLink", kRefOnly); + qmlRegisterUncreatableType (kQGroundControl, 1, 0, "InstrumentValueData", kRefOnly); qmlRegisterType (kQGroundControl, 1, 0, "LogReplayLinkController"); #if defined(QGC_ENABLE_MAVLINK_INSPECTOR) qmlRegisterUncreatableType (kQGroundControl, 1, 0, "MAVLinkChart", kRefOnly); @@ -528,7 +530,8 @@ void QGCApplication::_initCommon() qmlRegisterUncreatableType ("QGroundControl.FlightMap", 1, 0, "QGCMapPolygon", kRefOnly); qmlRegisterUncreatableType ("QGroundControl.FlightMap", 1, 0, "QGCGeoBoundingCube", kRefOnly); qmlRegisterUncreatableType ("QGroundControl.FlightMap", 1, 0, "TrajectoryPoints", kRefOnly); - qmlRegisterUncreatableType (kQGCControllers, 1, 0, "InstrumentValue", kRefOnly); + + qmlRegisterType (kQGCTemplates, 1, 0, "InstrumentValueArea"); qmlRegisterType ("QGroundControl.FlightMap", 1, 0, "QGCMapCircle"); @@ -536,7 +539,7 @@ void QGCApplication::_initCommon() qmlRegisterType (kQGCControllers, 1, 0, "ESP8266ComponentController"); qmlRegisterType (kQGCControllers, 1, 0, "ScreenToolsController"); qmlRegisterType (kQGCControllers, 1, 0, "PlanMasterController"); - qmlRegisterType (kQGCControllers, 1, 0, "ValuesWidgetController"); + qmlRegisterType (kQGCTemplates, 1, 0, "InstrumentValueArea"); qmlRegisterType (kQGCControllers, 1, 0, "QGCFileDialogController"); qmlRegisterType (kQGCControllers, 1, 0, "RCChannelMonitorController"); qmlRegisterType (kQGCControllers, 1, 0, "JoystickConfigController"); diff --git a/src/FlightMap/Widgets/InstrumentValue.qml b/src/QmlControls/InstrumentValue.qml similarity index 57% rename from src/FlightMap/Widgets/InstrumentValue.qml rename to src/QmlControls/InstrumentValue.qml index 348e4a374818c896822704edcd545be9a5297aca..c722d78856d8d514638fd783f93dfc052f980f32 100644 --- a/src/FlightMap/Widgets/InstrumentValue.qml +++ b/src/QmlControls/InstrumentValue.qml @@ -11,6 +11,7 @@ import QtQuick 2.12 import QtQuick.Layouts 1.2 import QtQuick.Controls 2.5 +import QGroundControl 1.0 import QGroundControl.Controls 1.0 import QGroundControl.ScreenTools 1.0 import QGroundControl.Palette 1.0 @@ -19,7 +20,7 @@ Item { id: root height: value.y + value.height - property var instrumentValue: null + property var instrumentValueData: null property bool recalcOk: false property var _rgFontSizes: [ ScreenTools.defaultFontPointSize, ScreenTools.smallFontPointSize, ScreenTools.mediumFontPointSize, ScreenTools.largeFontPointSize ] @@ -27,63 +28,74 @@ Item { property real _doubleDescent: ScreenTools.defaultFontDescent * 2 property real _tightDefaultFontHeight: ScreenTools.defaultFontPixelHeight - _doubleDescent property var _rgFontSizeTightHeights: [ _tightDefaultFontHeight * _rgFontSizeRatios[0] + 2, _tightDefaultFontHeight * _rgFontSizeRatios[1] + 2, _tightDefaultFontHeight * _rgFontSizeRatios[2] + 2, _tightDefaultFontHeight * _rgFontSizeRatios[3] + 2 ] + property real _tightHeight: _rgFontSizeTightHeights[instrumentValueData.instrumentValueArea.fontSize] + property real _fontSize: _rgFontSizes[instrumentValueData.instrumentValueArea.fontSize] + property real _horizontalLabelSpacing: ScreenTools.defaultFontPixelWidth property real _blankEntryHeight: ScreenTools.defaultFontPixelHeight * 2 + property bool _showIcon: instrumentValueData.icon || instrumentValueData.rangeType === InstrumentValueData.IconSelectRange // After fighting with using layout and/or anchors I gave up and just do a manual recalc to position items which ends up being much simpler function recalcPositions() { if (!recalcOk) { return } - var smallSpacing = 2 - if (instrumentValue.icon) { - if (instrumentValue.labelPosition === InstrumentValue.LabelAbove) { + var smallVerticalSpacing = 2 + var halfWidth = width / 2 + var halfHorizontalSpacing = _horizontalLabelSpacing / 2 + if (_showIcon) { + if (instrumentValueData.instrumentValueArea.orientation === InstrumentValueArea.VerticalOrientation) { valueIcon.x = (width - valueIcon.width) / 2 valueIcon.y = 0 value.x = (width - value.width) / 2 - value.y = valueIcon.height + smallSpacing + value.y = valueIcon.height + smallVerticalSpacing } else { - var iconPlusValueWidth = valueIcon.width + value.width + ScreenTools.defaultFontPixelWidth - valueIcon.x = (width - iconPlusValueWidth) / 2 + value.y = 0 // value assumed to be taller valueIcon.y = (value.height - valueIcon.height) / 2 - value.x = valueIcon.x + valueIcon.width + (ScreenTools.defaultFontPixelWidth / 2) - value.y = 0 + value.x = halfWidth + halfHorizontalSpacing + valueIcon.x = halfWidth - halfHorizontalSpacing - valueIcon.width } label.x = label.y = 0 } else { - // label above value - if (instrumentValue.text) { - label.x = (width - label.width) / 2 - label.y = 0 - value.y = label.height + smallSpacing + if (instrumentValueData.text) { + if (instrumentValueData.instrumentValueArea.orientation === InstrumentValueArea.VerticalOrientation) { + label.x = (width - label.width) / 2 + label.y = 0 + value.x = (width - value.width) / 2 + value.y = label.height + smallVerticalSpacing + } else { + value.y = 0 // value assumed to be taller + label.y = (value.height - label.height) / 2 + value.x = halfWidth + halfHorizontalSpacing + label.x = halfWidth - halfHorizontalSpacing - label.width + } } else { - value.y = 0 + value.x = (width - value.width) / 2 + value.y = (height - value.height) / 2 } - value.x = (width - value.width) / 2 valueIcon.x = valueIcon.y = 0 } } onRecalcOkChanged: recalcPositions() - onWidthChanged: recalcPositions() + onWidthChanged: recalcPositions() Connections { - target: instrumentValue - onIconChanged: recalcPositions() - onLabelPositionChanged: recalcPositions() + target: instrumentValueData + onIconChanged: recalcPositions() } QGCColoredImage { id: valueIcon - height: _rgFontSizeTightHeights[instrumentValue.fontSize] + height: _tightHeight width: height source: icon sourceSize.height: height fillMode: Image.PreserveAspectFit mipmap: true smooth: true - color: instrumentValue.isValidColor(instrumentValue.currentColor) ? instrumentValue.currentColor : qgcPal.text - opacity: instrumentValue.currentOpacity - visible: instrumentValue.icon + color: instrumentValueData.isValidColor(instrumentValueData.currentColor) ? instrumentValueData.currentColor : qgcPal.text + opacity: instrumentValueData.currentOpacity + visible: _showIcon onWidthChanged: root.recalcPositions() onHeightChanged: root.recalcPositions() @@ -91,17 +103,17 @@ Item { readonly property string iconPrefix: "/InstrumentValueIcons/" function updateIcon() { - if (instrumentValue.rangeType == InstrumentValue.IconSelectRange) { - icon = iconPrefix + instrumentValue.currentIcon - } else if (instrumentValue.icon) { - icon = iconPrefix + instrumentValue.icon + if (instrumentValueData.rangeType === InstrumentValueData.IconSelectRange) { + icon = iconPrefix + instrumentValueData.currentIcon + } else if (instrumentValueData.icon) { + icon = iconPrefix + instrumentValueData.icon } else { icon = "" } } Connections { - target: instrumentValue + target: instrumentValueData onRangeTypeChanged: valueIcon.updateIcon() onCurrentIconChanged: valueIcon.updateIcon() onIconChanged: valueIcon.updateIcon() @@ -117,28 +129,27 @@ Item { text: _settingsUnlocked ? qsTr("BLANK") : "" horizontalAlignment: Text.AlignHCenter verticalAlignment: Text.AlignVCenter - visible: !instrumentValue.fact + visible: !instrumentValueData.fact onWidthChanged: root.recalcPositions() onHeightChanged: root.recalcPositions() } QGCLabel { id: label - height: _rgFontSizeTightHeights[InstrumentValue.SmallFontSize] - font.pointSize: ScreenTools.smallFontPointSize - text: instrumentValue.text.toUpperCase() + height: _tightHeight + text: instrumentValueData.text verticalAlignment: Text.AlignVCenter - visible: instrumentValue.fact && instrumentValue.text && !instrumentValue.icon + visible: !_showIcon onWidthChanged: root.recalcPositions() onHeightChanged: root.recalcPositions() } QGCLabel { id: value - font.pointSize: _rgFontSizes[instrumentValue.fontSize] - text: visible ? (instrumentValue.fact.enumOrValueString + (instrumentValue.showUnits ? instrumentValue.fact.units : "")) : "" + font.pointSize: _fontSize + text: visible ? (instrumentValueData.fact.enumOrValueString + (instrumentValueData.showUnits ? instrumentValueData.fact.units : "")) : "" verticalAlignment: Text.AlignVCenter - visible: instrumentValue.fact + visible: instrumentValueData.fact onWidthChanged: root.recalcPositions() onHeightChanged: root.recalcPositions() } diff --git a/src/QmlControls/InstrumentValueArea.cc b/src/QmlControls/InstrumentValueArea.cc new file mode 100644 index 0000000000000000000000000000000000000000..20c387eeb3cb69b98a867dbbfa861ab12450f687 --- /dev/null +++ b/src/QmlControls/InstrumentValueArea.cc @@ -0,0 +1,363 @@ +/**************************************************************************** + * + * (c) 2009-2020 QGROUNDCONTROL PROJECT + * + * QGroundControl is licensed according to the terms in the file + * COPYING.md in the root of the source code directory. + * + ****************************************************************************/ + +#include "InstrumentValueArea.h" +#include "InstrumentValueData.h" +#include "QGCApplication.h" +#include "QGCCorePlugin.h" + +#include + +const QString InstrumentValueArea::_valuePageUserSettingsGroup ("ValuePage.userSettings"); +const QString InstrumentValueArea::valuePageDefaultSettingsGroup ("ValuePage.defaultSettings"); + +const char* InstrumentValueArea::_rowsKey = "rows"; +const char* InstrumentValueArea::_columnsKey = "columns"; +const char* InstrumentValueArea::_fontSizeKey = "fontSize"; +const char* InstrumentValueArea::_orientationKey = "orientation"; +const char* InstrumentValueArea::_versionKey = "version"; +const char* InstrumentValueArea::_factGroupNameKey = "groupName"; +const char* InstrumentValueArea::_factNameKey = "factName"; +const char* InstrumentValueArea::_textKey = "text"; +const char* InstrumentValueArea::_showUnitsKey = "showUnits"; +const char* InstrumentValueArea::_iconKey = "icon"; +const char* InstrumentValueArea::_rangeTypeKey = "rangeType"; +const char* InstrumentValueArea::_rangeValuesKey = "rangeValues"; +const char* InstrumentValueArea::_rangeColorsKey = "rangeColors"; +const char* InstrumentValueArea::_rangeIconsKey = "rangeIcons"; +const char* InstrumentValueArea::_rangeOpacitiesKey = "rangeOpacities"; + +const char* InstrumentValueArea::_deprecatedGroupKey = "ValuesWidget"; + +QStringList InstrumentValueArea::_iconNames; + +// Important: The indices of these strings must match the InstrumentValueArea::FontSize enum +const QStringList InstrumentValueArea::_fontSizeNames = { + QT_TRANSLATE_NOOP("InstrumentValueArea", "Default"), + QT_TRANSLATE_NOOP("InstrumentValueArea", "Small"), + QT_TRANSLATE_NOOP("InstrumentValueArea", "Medium"), + QT_TRANSLATE_NOOP("InstrumentValueArea", "Large"), +}; + +InstrumentValueArea::InstrumentValueArea(QQuickItem* parent) + : QQuickItem(parent) + , _rowValues(new QmlObjectListModel(this)) +{ + if (_iconNames.isEmpty()) { + QDir iconDir(":/InstrumentValueIcons/"); + _iconNames = iconDir.entryList(); + } + + _connectSignals(); +} + +InstrumentValueArea::InstrumentValueArea(const QString& defaultSettingsGroup) + : QQuickItem (nullptr) + , _defaultSettingsGroup (defaultSettingsGroup) + , _rowValues (new QmlObjectListModel(this)) +{ + + _connectSignals(); +} + +void InstrumentValueArea::_connectSignals(void) +{ + connect(this, &InstrumentValueArea::fontSizeChanged, this, &InstrumentValueArea::_saveSettings); + connect(this, &InstrumentValueArea::orientationChanged, this, &InstrumentValueArea::_saveSettings); +} + +void InstrumentValueArea::componentComplete(void) +{ + QQuickItem::componentComplete(); + + // We should know settingsGroup/defaultSettingsGroup now so we can load settings + _loadSettings(); +} + +InstrumentValueData* InstrumentValueArea::_createNewInstrumentValueWorker(QmlObjectListModel* rowModel) +{ + InstrumentValueData* value = new InstrumentValueData(this, rowModel); + + connect(value, &InstrumentValueData::factNameChanged, this, &InstrumentValueArea::_saveSettings); + connect(value, &InstrumentValueData::factGroupNameChanged, this, &InstrumentValueArea::_saveSettings); + connect(value, &InstrumentValueData::textChanged, this, &InstrumentValueArea::_saveSettings); + connect(value, &InstrumentValueData::showUnitsChanged, this, &InstrumentValueArea::_saveSettings); + connect(value, &InstrumentValueData::iconChanged, this, &InstrumentValueArea::_saveSettings); + connect(value, &InstrumentValueData::rangeTypeChanged, this, &InstrumentValueArea::_saveSettings); + connect(value, &InstrumentValueData::rangeValuesChanged, this, &InstrumentValueArea::_saveSettings); + connect(value, &InstrumentValueData::rangeColorsChanged, this, &InstrumentValueArea::_saveSettings); + connect(value, &InstrumentValueData::rangeOpacitiesChanged, this, &InstrumentValueArea::_saveSettings); + connect(value, &InstrumentValueData::rangeIconsChanged, this, &InstrumentValueArea::_saveSettings); + + return value; +} + +InstrumentValueData* InstrumentValueArea::appendColumn(int rowIndex) +{ + InstrumentValueData* newValue = nullptr; + + if (rowIndex >= 0 && rowIndex < _rowValues->count()) { + QmlObjectListModel* row = _rowValues->value(rowIndex); + newValue = _createNewInstrumentValueWorker(row); + row->append(newValue); + } + _saveSettings(); + + return newValue; +} + +void InstrumentValueArea::deleteLastColumn(int rowIndex) +{ + if (rowIndex >= 0 && rowIndex < _rowValues->count()) { + QmlObjectListModel* row = _rowValues->value(rowIndex); + + if (rowIndex != 0 || row->count() > 1) { + row->removeAt(row->count() - 1); + } + if (row->count() == 0) { + // Last column was deleted, delete the row as well + _rowValues->removeAt(rowIndex); + } + } + _saveSettings(); +} + +QmlObjectListModel* InstrumentValueArea::appendRow(bool addBlanksColumn) +{ + QmlObjectListModel* newRow = new QmlObjectListModel(_rowValues); + _rowValues->append(newRow); + int rowIndex = _rowValues->count() - 1; + if (addBlanksColumn) { + appendColumn(rowIndex); + } + _saveSettings(); + return newRow; +} + +QmlObjectListModel* InstrumentValueArea::insertRow(int atIndex, bool addBlanksColumn) +{ + QmlObjectListModel* newRow = nullptr; + + if (atIndex >= 0 && atIndex < _rowValues->count() + 1) { + QmlObjectListModel* newRow = new QmlObjectListModel(_rowValues); + _rowValues->insert(atIndex, newRow); + if (addBlanksColumn) { + appendColumn(atIndex); + } + _saveSettings(); + } + return newRow; +} + +void InstrumentValueArea::deleteRow(int rowIndex) +{ + if (rowIndex >= 0 && rowIndex < _rowValues->count()) { + if (_rowValues->count() > 1) { + _rowValues->removeAt(rowIndex); + } + _saveSettings(); + } +} + +bool InstrumentValueArea::_validRowIndex(int rowIndex) +{ + return rowIndex >= 0 && rowIndex < _rowValues->count(); +} + +void InstrumentValueArea::_checkForDeprecatedSettings(void) +{ + QSettings settings; + + if (settings.childGroups().contains(_deprecatedGroupKey)) { + settings.remove(_deprecatedGroupKey); + qgcApp()->showAppMessage(tr("Instrument Values"), tr("The support for custom instrument values display has changed. Because of this the display will be reset to the new default setup. You will need to modify it again to suit your needs.")); + } +} + +void InstrumentValueArea::_saveSettings(void) +{ + if (_preventSaveSettings) { + return; + } + + QSettings settings; + + if (_userSettingsGroup.isEmpty()) { + // This means we are setting up default settings + settings.beginGroup(_defaultSettingsGroup); + } else { + // This means we are saving user modifications + settings.remove(_defaultSettingsGroup); + settings.beginGroup(_userSettingsGroup); + } + + settings.remove(""); // Remove any previous settings + + settings.setValue(_versionKey, 1); + settings.setValue(_fontSizeKey, _fontSize); + settings.setValue(_orientationKey, _orientation); + + settings.beginWriteArray(_rowsKey); + + for (int rowIndex=0; rowIndex<_rowValues->count(); rowIndex++) { + QmlObjectListModel* colValues = _rowValues->value(rowIndex); + + settings.setArrayIndex(rowIndex); + settings.beginWriteArray(_columnsKey); + + for (int colIndex=0; colIndexcount(); colIndex++) { + InstrumentValueData* value = colValues->value(colIndex); + + settings.setArrayIndex(colIndex); + + settings.setValue(_textKey, value->text()); + settings.setValue(_showUnitsKey, value->showUnits()); + settings.setValue(_iconKey, value->icon()); + settings.setValue(_rangeTypeKey, value->rangeType()); + + if (value->rangeType() != InstrumentValueData::NoRangeInfo) { + settings.setValue(_rangeValuesKey, value->rangeValues()); + } + + switch (value->rangeType()) { + case InstrumentValueData::NoRangeInfo: + break; + case InstrumentValueData::ColorRange: + settings.setValue(_rangeColorsKey, value->rangeColors()); + break; + case InstrumentValueData::OpacityRange: + settings.setValue(_rangeOpacitiesKey, value->rangeOpacities()); + break; + case InstrumentValueData::IconSelectRange: + settings.setValue(_rangeIconsKey, value->rangeIcons()); + break; + } + + if (value->fact()) { + settings.setValue(_factGroupNameKey, value->factGroupName()); + settings.setValue(_factNameKey, value->factName()); + } else { + settings.setValue(_factGroupNameKey, ""); + settings.setValue(_factNameKey, ""); + } + } + + settings.endArray(); + } + + settings.endArray(); +} + +void InstrumentValueArea::_loadSettings(void) +{ + _checkForDeprecatedSettings(); + + QSettings settings; + + _rowValues->deleteLater(); + _rowValues = new QmlObjectListModel(this); + emit rowValuesChanged(_rowValues); + + if (!settings.childGroups().contains(_userSettingsGroup)) { + qgcApp()->toolbox()->corePlugin()->instrumentValueAreaCreateDefaultSettings(_defaultSettingsGroup); + } + + _preventSaveSettings = true; + + if (settings.childGroups().contains(_defaultSettingsGroup)) { + settings.beginGroup(_defaultSettingsGroup); + } else { + settings.beginGroup(_userSettingsGroup); + } + + int version = settings.value(_versionKey, 0).toInt(); + if (version != 1) { + qgcApp()->showAppMessage(tr("Load Settings"), tr("Settings version %1 for %2 is not supported. Setup will be reset to defaults.").arg(version).arg(_userSettingsGroup)); + settings.remove(""); + qgcApp()->toolbox()->corePlugin()->instrumentValueAreaCreateDefaultSettings(_defaultSettingsGroup); + } + _fontSize = settings.value(_fontSizeKey, DefaultFontSize).value(); + _orientation = settings.value(_orientationKey, VerticalOrientation).value(); + + int cRows = settings.beginReadArray(_rowsKey); + + for (int rowIndex=0; rowIndexsetFact(settings.value(_factGroupNameKey).toString(), factName); + } + + value->setText (settings.value(_textKey).toString()); + value->setShowUnits (settings.value(_showUnitsKey, true).toBool()); + value->setIcon (settings.value(_iconKey).toString()); + value->setRangeType (settings.value(_rangeTypeKey, InstrumentValueData::NoRangeInfo).value()); + + if (value->rangeType() != InstrumentValueData::NoRangeInfo) { + value->setRangeValues(settings.value(_rangeValuesKey).value()); + } + switch (value->rangeType()) { + case InstrumentValueData::NoRangeInfo: + break; + case InstrumentValueData::ColorRange: + value->setRangeColors(settings.value(_rangeColorsKey).value()); + break; + case InstrumentValueData::OpacityRange: + value->setRangeOpacities(settings.value(_rangeOpacitiesKey).value()); + break; + case InstrumentValueData::IconSelectRange: + value->setRangeIcons(settings.value(_rangeIconsKey).value()); + break; + } + } + + settings.endArray(); + } + + settings.endArray(); + + _preventSaveSettings = false; + + // Use defaults if nothing there + if (_rowValues->count() == 0) { + _rowValues->deleteLater(); + emit rowValuesChanged(_rowValues); + } +} + +void InstrumentValueArea::resetToDefaults(void) +{ + QSettings settings; + + settings.remove(_userSettingsGroup); + + _loadSettings(); +} + +QString InstrumentValueArea::_pascalCase(const QString& text) +{ + return text[0].toUpper() + text.right(text.length() - 1); +} + +void InstrumentValueArea::setFontSize(FontSize fontSize) +{ + if (fontSize != _fontSize) { + _fontSize = fontSize; + emit fontSizeChanged(fontSize); + } +} diff --git a/src/QmlControls/InstrumentValueArea.h b/src/QmlControls/InstrumentValueArea.h new file mode 100644 index 0000000000000000000000000000000000000000..1d8943b8b0cecb7a6d5d0d06d7434de932e7b22c --- /dev/null +++ b/src/QmlControls/InstrumentValueArea.h @@ -0,0 +1,135 @@ +/**************************************************************************** + * + * (c) 2009-2020 QGROUNDCONTROL PROJECT + * + * QGroundControl is licensed according to the terms in the file + * COPYING.md in the root of the source code directory. + * + ****************************************************************************/ + +#pragma once + +#include "FactSystem.h" +#include "QmlObjectListModel.h" +#include "QGCApplication.h" + +#include + +class InstrumentValueData; + +class InstrumentValueArea : public QQuickItem +{ + Q_OBJECT + +public: + InstrumentValueArea(QQuickItem *parent = nullptr); + InstrumentValueArea(const QString& defaultSettingsGroup); + + enum Orientation { + HorizontalOrientation=0, // Labels will be to the left of the value + VerticalOrientation // Labels will be above the value + }; + Q_ENUMS(Orientation) + + enum FontSize { + DefaultFontSize=0, + SmallFontSize, + MediumFontSize, + LargeFontSize, + }; + Q_ENUMS(FontSize) + + // valuePageDefaultSettingsGroup: + // This is the setting group name for default settings which are used when the user has not modified anything from the default setup. These settings will be overwritten + // prior to each use by the call to QGCCorePlugin::instrumentValueAreaCreateDefaultSettings. + + // valuePageUserSettingsGroup: + // This is the settings group name for user modified settings. Settings will be saved to here whenever the user modified anything. Also at that point in time the + // defaults settings group will be removed. + + // The combination of the two valuePage*SettingsGroup values allows each InstrumentValueArea to have it's own persistence space. + + Q_PROPERTY(QString valuePageDefaultSettingsGroup MEMBER valuePageDefaultSettingsGroup CONSTANT) + Q_PROPERTY(QString valuePageUserSettingsGroup MEMBER _valuePageUserSettingsGroup CONSTANT) + Q_PROPERTY(QString userSettingsGroup MEMBER _userSettingsGroup NOTIFY userSettingsGroupChanged) + Q_PROPERTY(QString defaultSettingsGroup MEMBER _defaultSettingsGroup NOTIFY defaultSettingsGroupChanged) + Q_PROPERTY(Orientation orientation MEMBER _orientation NOTIFY orientationChanged) + Q_PROPERTY(QStringList iconNames READ iconNames CONSTANT) + Q_PROPERTY(FontSize fontSize READ fontSize WRITE setFontSize NOTIFY fontSizeChanged) + Q_PROPERTY(QStringList fontSizeNames MEMBER _fontSizeNames CONSTANT) + Q_PROPERTY(QmlObjectListModel* rowValues MEMBER _rowValues NOTIFY rowValuesChanged) + + Q_INVOKABLE InstrumentValueData* appendColumn (int rowIndex); + Q_INVOKABLE void deleteLastColumn (int rowIndex); + Q_INVOKABLE QmlObjectListModel* appendRow (bool addBlanksColumn = true); + Q_INVOKABLE QmlObjectListModel* insertRow (int atIndex, bool addBlanksColumn = true); + Q_INVOKABLE void deleteRow (int rowIndex); + Q_INVOKABLE void resetToDefaults (void); + + FontSize fontSize (void) const { return _fontSize; } + QmlObjectListModel* rowValues (void) { return _rowValues; } + QStringList iconNames (void) const { return _iconNames; } + + void setFontSize(FontSize fontSize); + + // Override from QQmlParserStatus + void componentComplete(void) final; + + static const QString valuePageDefaultSettingsGroup; + +signals: + void userSettingsGroupChanged (const QString& userSettingsGroup); + void defaultSettingsGroupChanged(const QString& defaultSettingsGroup); + void rowValuesChanged (QmlObjectListModel* rowValues); + void orientationChanged (Orientation orientation); + void fontSizeChanged (FontSize fontSize); + +private slots: + void _saveSettings(void); + +private: + void _connectSignals (void); + void _checkForDeprecatedSettings (void); + bool _validRowIndex (int rowIndex); + InstrumentValueData* _createNewInstrumentValueWorker (QmlObjectListModel* rowModel); + void _loadSettings (void); + QString _pascalCase (const QString& text); + + Q_DISABLE_COPY(InstrumentValueArea) + + QString _defaultSettingsGroup; // Settings group to read from if the user has not modified from the default settings + QString _userSettingsGroup; // Settings group to read from for user modified settings + Orientation _orientation = VerticalOrientation; + FontSize _fontSize = DefaultFontSize; + QmlObjectListModel* _rowValues = nullptr; + bool _preventSaveSettings = false; + + // These are user facing string for the various enums. + static QStringList _iconNames; + static const QStringList _fontSizeNames; + + static const QString _valuePageUserSettingsGroup; + + static const char* _versionKey; + static const char* _rowsKey; + static const char* _columnsKey; + static const char* _orientationKey; + static const char* _fontSizeKey; + static const char* _factGroupNameKey; + static const char* _factNameKey; + static const char* _textKey; + static const char* _showUnitsKey; + static const char* _iconKey; + static const char* _rangeTypeKey; + static const char* _rangeValuesKey; + static const char* _rangeColorsKey; + static const char* _rangeIconsKey; + static const char* _rangeOpacitiesKey; + + static const char* _deprecatedGroupKey; +}; + +QML_DECLARE_TYPE(InstrumentValueArea) + +Q_DECLARE_METATYPE(InstrumentValueArea::FontSize) +Q_DECLARE_METATYPE(InstrumentValueArea::Orientation) diff --git a/src/QmlControls/InstrumentValueArea.qml b/src/QmlControls/InstrumentValueArea.qml new file mode 100644 index 0000000000000000000000000000000000000000..a29b23d1af5550a17d8b36cb3e0f169e67779879 --- /dev/null +++ b/src/QmlControls/InstrumentValueArea.qml @@ -0,0 +1,154 @@ +/**************************************************************************** + * + * (c) 2009-2020 QGROUNDCONTROL PROJECT + * + * QGroundControl is licensed according to the terms in the file + * COPYING.md in the root of the source code directory. + * + ****************************************************************************/ + +import QtQuick 2.12 +import QtQuick.Layouts 1.2 +import QtQuick.Controls 2.5 +import QtQml 2.12 + +import QGroundControl.Templates 1.0 as T +import QGroundControl.Controls 1.0 +import QGroundControl.ScreenTools 1.0 +import QGroundControl.Controllers 1.0 +import QGroundControl.Palette 1.0 +import QGroundControl.FlightMap 1.0 +import QGroundControl 1.0 + +T.InstrumentValueArea { + id: _root + height: innerColumn.height + + property bool settingsUnlocked: false + + property real _margins: ScreenTools.defaultFontPixelWidth / 2 + property int _colMax: 4 + property real _columnButtonWidth: ScreenTools.minTouchPixels / 2 + property real _columnButtonHeight: ScreenTools.minTouchPixels + property real _columnButtonSpacing: 2 + property real _columnButtonsTotalHeight: (_columnButtonHeight * 2) + _columnButtonSpacing + + Column { + id: innerColumn + width: parent.width + spacing: Math.round(ScreenTools.defaultFontPixelHeight / 2) + + Repeater { + id: rowRepeater + model: rowValues + + Column { + id: rowRepeaterLayout + spacing: 1 + + property int rowIndex: index + + Row { + id: columnRow + spacing: 1 + + Repeater { + id: columnRepeater + model: object + + property real _interColumnSpacing: (columnRepeater.count - (settingsUnlocked ? 0 : 1)) * columnRow.spacing + property real columnWidth: (pageWidth - (settingsUnlocked ? _columnButtonWidth : 0) - _interColumnSpacing) / columnRepeater.count + property bool componentCompleted: false + + Component.onCompleted: componentCompleted = true + onItemAdded: valueItemMouseAreaComponent.createObject(item, { "instrumentValueData": object.get(index), "rowIndex": index }) + + InstrumentValue { + id: columnItem + anchors.verticalCenter: parent.verticalCenter + width: columnRepeater.columnWidth + recalcOk: columnRepeater.componentCompleted + instrumentValueData: object + } + } // Repeater - columns + + ColumnLayout { + id: columnsButtonsLayout + width: _columnButtonWidth + spacing: _columnButtonSpacing + visible: settingsUnlocked + + QGCButton { + Layout.fillHeight: true + Layout.preferredHeight: ScreenTools.minTouchPixels + Layout.preferredWidth: parent.width + text: qsTr("+") + onClicked: appendColumn(rowRepeaterLayout.rowIndex) + } + + QGCButton { + Layout.fillHeight: true + Layout.preferredHeight: ScreenTools.minTouchPixels + Layout.preferredWidth: parent.width + text: qsTr("-") + enabled: index !== 0 || columnRepeater.count !== 1 + onClicked: deleteLastColumn(rowRepeaterLayout.rowIndex) + } + } + } // RowLayout + + RowLayout { + width: parent.width + height: ScreenTools.defaultFontPixelWidth * 2 + spacing: 1 + visible: settingsUnlocked + + QGCButton { + Layout.fillWidth: true + Layout.preferredHeight: ScreenTools.defaultFontPixelWidth * 2 + text: qsTr("+") + onClicked: insertRow(index + 1) + } + + QGCButton { + Layout.fillWidth: true + Layout.preferredHeight: ScreenTools.defaultFontPixelWidth * 2 + text: qsTr("-") + enabled: index !== 0 + onClicked: deleteRow(index) + } + } + } + } // Repeater - rows + + QGCButton { + anchors.left: parent.left + anchors.right: parent.right + text: qsTr("Reset To Defaults") + visible: settingsUnlocked + onClicked: resetToDefaults() + } + + Component { + id: valueItemMouseAreaComponent + + MouseArea { + anchors.centerIn: parent + width: parent.width + height: _columnButtonsTotalHeight + visible: settingsUnlocked + + property var instrumentValueData + property int rowIndex + + onClicked: mainWindow.showPopupDialog(valueEditDialog, { instrumentValueData: instrumentValueData }) + } + } + + Component { + id: valueEditDialog + + InstrumentValueEditDialog { } + } + } +} diff --git a/src/QmlControls/InstrumentValueData.cc b/src/QmlControls/InstrumentValueData.cc new file mode 100644 index 0000000000000000000000000000000000000000..6421a11f3ffa28a321ab8fc357109fa047acc445 --- /dev/null +++ b/src/QmlControls/InstrumentValueData.cc @@ -0,0 +1,366 @@ +/**************************************************************************** + * + * (c) 2009-2020 QGROUNDCONTROL PROJECT + * + * QGroundControl is licensed according to the terms in the file + * COPYING.md in the root of the source code directory. + * + ****************************************************************************/ + +#include "InstrumentValueData.h" +#include "InstrumentValueArea.h" +#include "QGCApplication.h" +#include "QGCCorePlugin.h" + +#include + +const char* InstrumentValueData::_vehicleFactGroupName = "Vehicle"; + +// Important: The indices of these strings must match the InstrumentValueData::RangeType enum +const QStringList InstrumentValueData::_rangeTypeNames = { + QT_TRANSLATE_NOOP("InstrumentValue", "None"), + QT_TRANSLATE_NOOP("InstrumentValue", "Color"), + QT_TRANSLATE_NOOP("InstrumentValue", "Opacity"), + QT_TRANSLATE_NOOP("InstrumentValue", "Icon"), +}; + +InstrumentValueData::InstrumentValueData(InstrumentValueArea* instrumentValueArea, QObject *parent) + : QObject (parent) + , _instrumentValueArea (instrumentValueArea) +{ + MultiVehicleManager* multiVehicleManager = qgcApp()->toolbox()->multiVehicleManager(); + connect(multiVehicleManager, &MultiVehicleManager::activeVehicleChanged, this, &InstrumentValueData::_activeVehicleChanged); + _activeVehicleChanged(multiVehicleManager->activeVehicle()); + + connect(this, &InstrumentValueData::rangeTypeChanged, this, &InstrumentValueData::_resetRangeInfo); + connect(this, &InstrumentValueData::rangeTypeChanged, this, &InstrumentValueData::_updateRanges); + connect(this, &InstrumentValueData::rangeValuesChanged, this, &InstrumentValueData::_updateRanges); + connect(this, &InstrumentValueData::rangeColorsChanged, this, &InstrumentValueData::_updateRanges); + connect(this, &InstrumentValueData::rangeOpacitiesChanged, this, &InstrumentValueData::_updateRanges); + connect(this, &InstrumentValueData::rangeIconsChanged, this, &InstrumentValueData::_updateRanges); +} + +void InstrumentValueData::_activeVehicleChanged(Vehicle* activeVehicle) +{ + if (!activeVehicle) { + activeVehicle = qgcApp()->toolbox()->multiVehicleManager()->offlineEditingVehicle(); + } + + if (_fact) { + disconnect(_fact, &Fact::rawValueChanged, this, &InstrumentValueData::_updateColor); + } + + _activeVehicle = activeVehicle; + + _factGroupNames.clear(); + _factGroupNames = _activeVehicle->factGroupNames(); + for (QString& name: _factGroupNames) { + name[0] = name[0].toUpper(); + } + _factGroupNames.prepend(_vehicleFactGroupName); + emit factGroupNamesChanged(_factGroupNames); + + if (_fact) { + _fact = nullptr; + + FactGroup* factGroup = nullptr; + if (_factGroupName == _vehicleFactGroupName) { + factGroup = _activeVehicle; + } else { + factGroup = _activeVehicle->getFactGroup(_factGroupName); + } + + if (factGroup) { + _fact = factGroup->getFact(_factName); + } + emit factChanged(_fact); + + connect(_fact, &Fact::rawValueChanged, this, &InstrumentValueData::_updateRanges); + } + + _updateRanges(); +} + +void InstrumentValueData::clearFact(void) +{ + _fact = nullptr; + _factName.clear(); + _factGroupName.clear(); + _factValueNames.clear(); + _text.clear(); + _icon.clear(); + _showUnits = true; + + emit factValueNamesChanged (_factValueNames); + emit factChanged (_fact); + emit factNameChanged (_factName); + emit factGroupNameChanged (_factGroupName); + emit textChanged (_text); + emit iconChanged (_icon); + emit showUnitsChanged (_showUnits); +} + +void InstrumentValueData::setFact(const QString& factGroupName, const QString& factName) +{ + if (_fact) { + disconnect(_fact, &Fact::rawValueChanged, this, &InstrumentValueData::_updateRanges); + _fact = nullptr; + } + + FactGroup* factGroup = nullptr; + if (factGroupName == _vehicleFactGroupName) { + factGroup = _activeVehicle; + } else { + factGroup = _activeVehicle->getFactGroup(factGroupName); + } + + _factValueNames.clear(); + _factValueNames = factGroup->factNames(); + for (QString& name: _factValueNames) { + name[0] = name[0].toUpper(); + } + + QString nonEmptyFactName; + if (factGroup) { + if (factName.isEmpty()) { + nonEmptyFactName = _factValueNames[0]; + } else { + nonEmptyFactName = factName; + } + _fact = factGroup->getFact(nonEmptyFactName); + } + + if (_fact) { + _factGroupName = factGroupName; + _factName = nonEmptyFactName; + + connect(_fact, &Fact::rawValueChanged, this, &InstrumentValueData::_updateRanges); + } else { + _factName.clear(); + _factGroupName.clear(); + } + + emit factValueNamesChanged (_factValueNames); + emit factChanged (_fact); + emit factNameChanged (_factName); + emit factGroupNameChanged (_factGroupName); + + _updateRanges(); +} + +void InstrumentValueData::setText(const QString& text) +{ + if (text != _text) { + _text = text; + emit textChanged(text); + } +} + +void InstrumentValueData::setShowUnits(bool showUnits) +{ + if (showUnits != _showUnits) { + _showUnits = showUnits; + emit showUnitsChanged(showUnits); + } +} + +void InstrumentValueData::setIcon(const QString& icon) +{ + if (icon != _icon) { + _icon = icon; + emit iconChanged(_icon); + } +} + +void InstrumentValueData::setRangeType(RangeType rangeType) +{ + if (rangeType != _rangeType) { + _rangeType = rangeType; + emit rangeTypeChanged(rangeType); + } +} + +void InstrumentValueData::setRangeValues(const QVariantList& rangeValues) +{ + _rangeValues = rangeValues; + emit rangeValuesChanged(rangeValues); +} + +void InstrumentValueData::setRangeColors (const QVariantList& rangeColors) +{ + _rangeColors = rangeColors; + emit rangeColorsChanged(rangeColors); +} + +void InstrumentValueData::setRangeIcons(const QVariantList& rangeIcons) +{ + _rangeIcons = rangeIcons; + emit rangeIconsChanged(rangeIcons); +} + +void InstrumentValueData::setRangeOpacities(const QVariantList& rangeOpacities) +{ + _rangeOpacities = rangeOpacities; + emit rangeOpacitiesChanged(rangeOpacities); +} + +void InstrumentValueData::_resetRangeInfo(void) +{ + _rangeValues.clear(); + _rangeColors.clear(); + _rangeOpacities.clear(); + _rangeIcons.clear(); + + if (_rangeType != NoRangeInfo) { + _rangeValues = { 0.0, 100.0 }; + } + for (int i=0; i<_rangeValues.count() + 1; i++) { + switch (_rangeType) { + case NoRangeInfo: + break; + case ColorRange: + _rangeColors.append(QColor("green")); + break; + case OpacityRange: + _rangeOpacities.append(1.0); + break; + case IconSelectRange: + _rangeIcons.append(_instrumentValueArea->iconNames()[0]); + break; + } + } + + emit rangeValuesChanged (_rangeValues); + emit rangeColorsChanged (_rangeColors); + emit rangeOpacitiesChanged (_rangeOpacities); + emit rangeIconsChanged (_rangeIcons); +} + +void InstrumentValueData::addRangeValue(void) +{ + _rangeValues.append(_rangeValues.last().toDouble() + 1); + + switch (_rangeType) { + case NoRangeInfo: + break; + case ColorRange: + _rangeColors.append(QColor("green")); + break; + case OpacityRange: + _rangeOpacities.append(1.0); + break; + case IconSelectRange: + _rangeIcons.append(_instrumentValueArea->iconNames()[0]); + break; + } + + emit rangeValuesChanged (_rangeValues); + emit rangeColorsChanged (_rangeColors); + emit rangeOpacitiesChanged (_rangeOpacities); + emit rangeIconsChanged (_rangeIcons); +} + +void InstrumentValueData::removeRangeValue(int index) +{ + if (_rangeValues.count() < 2 || index <0 || index >= _rangeValues.count()) { + return; + } + + _rangeValues.removeAt(index); + + switch (_rangeType) { + case NoRangeInfo: + break; + case ColorRange: + _rangeColors.removeAt(index + 1); + break; + case OpacityRange: + _rangeOpacities.removeAt(index + 1); + break; + case IconSelectRange: + _rangeIcons.removeAt(index + 1); + break; + } + + emit rangeValuesChanged (_rangeValues); + emit rangeColorsChanged (_rangeColors); + emit rangeOpacitiesChanged (_rangeOpacities); + emit rangeIconsChanged (_rangeIcons); +} + +void InstrumentValueData::_updateRanges(void) +{ + _updateColor(); + _updateIcon(); + _updateOpacity(); +} + +void InstrumentValueData::_updateColor(void) +{ + QColor newColor; + + int rangeIndex = -1; + + if (_rangeType == ColorRange && _fact) { + rangeIndex =_currentRangeIndex(_fact->rawValue().toDouble()); + } + if (rangeIndex != -1) { + newColor = _rangeColors[rangeIndex].value(); + } + + if (newColor != _currentColor) { + _currentColor = newColor; + emit currentColorChanged(_currentColor); + } +} + +void InstrumentValueData::_updateOpacity(void) +{ + double newOpacity = 1.0; + + int rangeIndex = -1; + + if (_rangeType == OpacityRange && _fact) { + rangeIndex =_currentRangeIndex(_fact->rawValue().toDouble()); + } + if (rangeIndex != -1) { + newOpacity = _rangeOpacities[rangeIndex].toDouble(); + } + + if (!qFuzzyCompare(newOpacity, _currentOpacity)) { + _currentOpacity = newOpacity; + emit currentOpacityChanged(newOpacity); + } +} + +void InstrumentValueData::_updateIcon(void) +{ + QString newIcon; + + int rangeIndex = -1; + + if (_rangeType == IconSelectRange && _fact) { + rangeIndex =_currentRangeIndex(_fact->rawValue().toDouble()); + } + if (rangeIndex != -1) { + newIcon = _rangeIcons[rangeIndex].toString(); + } + + if (newIcon != _currentIcon) { + _currentIcon = newIcon; + emit currentIconChanged(newIcon); + } +} + +int InstrumentValueData::_currentRangeIndex(const QVariant& value) +{ + if (qIsNaN(value.toDouble())) { + return 0; + } + for (int i=0; i<_rangeValues.count(); i++) { + if (value.toDouble() <= _rangeValues[i].toDouble()) { + return i; + } + } + return _rangeValues.count(); +} diff --git a/src/QmlControls/InstrumentValueData.h b/src/QmlControls/InstrumentValueData.h new file mode 100644 index 0000000000000000000000000000000000000000..d636608e045c97ad03009e7edd2e10e5895df720 --- /dev/null +++ b/src/QmlControls/InstrumentValueData.h @@ -0,0 +1,147 @@ +/**************************************************************************** + * + * (c) 2009-2020 QGROUNDCONTROL PROJECT + * + * QGroundControl is licensed according to the terms in the file + * COPYING.md in the root of the source code directory. + * + ****************************************************************************/ + +#pragma once + +#include "FactSystem.h" +#include "QmlObjectListModel.h" +#include "QGCApplication.h" + +#include + +class InstrumentValueArea; + +class InstrumentValueData : public QObject +{ + Q_OBJECT + +public: + enum RangeType { + NoRangeInfo = 0, + ColorRange, + OpacityRange, + IconSelectRange, + }; + Q_ENUMS(RangeType) + + explicit InstrumentValueData(InstrumentValueArea* instrumentValueArea, QObject *parent = nullptr); + + Q_PROPERTY(InstrumentValueArea* instrumentValueArea MEMBER _instrumentValueArea CONSTANT) + Q_PROPERTY(QStringList factGroupNames MEMBER _factGroupNames NOTIFY factGroupNamesChanged) + Q_PROPERTY(QStringList factValueNames MEMBER _factValueNames NOTIFY factValueNamesChanged) + Q_PROPERTY(QString factGroupName READ factGroupName NOTIFY factGroupNameChanged) + Q_PROPERTY(QString factName READ factName NOTIFY factNameChanged) + Q_PROPERTY(Fact* fact READ fact NOTIFY factChanged) + Q_PROPERTY(QString text READ text WRITE setText NOTIFY textChanged) + Q_PROPERTY(QString icon READ icon WRITE setIcon NOTIFY iconChanged) ///< If !isEmpty icon will be show instead of label + Q_PROPERTY(bool showUnits READ showUnits WRITE setShowUnits NOTIFY showUnitsChanged) + Q_PROPERTY(QStringList rangeTypeNames MEMBER _rangeTypeNames CONSTANT) + Q_PROPERTY(RangeType rangeType READ rangeType WRITE setRangeType NOTIFY rangeTypeChanged) + Q_PROPERTY(QVariantList rangeValues READ rangeValues WRITE setRangeValues NOTIFY rangeValuesChanged) + Q_PROPERTY(QVariantList rangeColors READ rangeColors WRITE setRangeColors NOTIFY rangeColorsChanged) + Q_PROPERTY(QVariantList rangeIcons READ rangeIcons WRITE setRangeIcons NOTIFY rangeIconsChanged) + Q_PROPERTY(QVariantList rangeOpacities READ rangeOpacities WRITE setRangeOpacities NOTIFY rangeOpacitiesChanged) + Q_PROPERTY(QColor currentColor MEMBER _currentColor NOTIFY currentColorChanged) + Q_PROPERTY(double currentOpacity MEMBER _currentOpacity NOTIFY currentOpacityChanged) + Q_PROPERTY(QString currentIcon MEMBER _currentIcon NOTIFY currentIconChanged) + + Q_INVOKABLE void setFact (const QString& factGroupName, const QString& factName); + Q_INVOKABLE void clearFact (void); + Q_INVOKABLE bool isValidColor (const QColor& color) { return color.isValid(); } + Q_INVOKABLE QColor invalidColor (void) { return QColor(); } + Q_INVOKABLE void addRangeValue (void); + Q_INVOKABLE void removeRangeValue(int index); + + QString factGroupName (void) const { return _factGroupName; } + QString factName (void) const { return _factName; } + Fact* fact (void) { return _fact; } + QString text (void) const { return _text; } + bool showUnits (void) const { return _showUnits; } + QString icon (void) const { return _icon; } + RangeType rangeType (void) const { return _rangeType; } + QVariantList rangeValues (void) const { return _rangeValues; } + QVariantList rangeColors (void) const { return _rangeColors; } + QVariantList rangeIcons (void) const { return _rangeIcons; } + QVariantList rangeOpacities (void) const { return _rangeOpacities; } + void setText (const QString& text); + void setShowUnits (bool showUnits); + void setIcon (const QString& icon); + void setRangeType (RangeType rangeType); + void setRangeValues (const QVariantList& rangeValues); + void setRangeColors (const QVariantList& rangeColors); + void setRangeIcons (const QVariantList& rangeIcons); + void setRangeOpacities (const QVariantList& rangeOpacities); + +signals: + void factChanged (Fact* fact); + void factNameChanged (const QString& factName); + void factGroupNameChanged (const QString& factGroup); + void textChanged (QString text); + void showUnitsChanged (bool showUnits); + void iconChanged (const QString& icon); + void factGroupNamesChanged (const QStringList& factGroupNames); + void factValueNamesChanged (const QStringList& factValueNames); + void rangeTypeChanged (RangeType rangeType); + void rangeValuesChanged (const QVariantList& rangeValues); + void rangeColorsChanged (const QVariantList& rangeColors); + void rangeIconsChanged (const QVariantList& rangeIcons); + void rangeOpacitiesChanged (const QVariantList& rangeOpacities); + void currentColorChanged (const QColor& currentColor); + void currentOpacityChanged (double currentOpacity); + void currentIconChanged (const QString& currentIcon); + +private slots: + void _resetRangeInfo (void); + void _updateRanges (void); + void _activeVehicleChanged (Vehicle* activeVehicle); + +private: + int _currentRangeIndex (const QVariant& value); + void _updateColor (void); + void _updateIcon (void); + void _updateOpacity (void); + + InstrumentValueArea* _instrumentValueArea = nullptr; + Vehicle* _activeVehicle = nullptr; + QmlObjectListModel* _rowModel = nullptr; + Fact* _fact = nullptr; + QString _factName; + QString _factGroupName; + QString _text; + bool _showUnits = true; + QString _icon; + QStringList _factGroupNames; + QStringList _factValueNames; + QColor _currentColor; + double _currentOpacity = 1.0; + QString _currentIcon; + + // Ranges allow you to specifiy semantics to apply when a value is within a certain range. + // The limits for each section of the range are specified in _rangeValues. With the first + // element indicating a range from that value to -infinity and the last element indicating + // a range from the value to +infinity. + // + // The semantics to apply are defined by the _rangeType value. With the semantic lists having + // a specific value for each section of the range. There should be _rangeValues.count() + 2 + // semantic values in the apppropriate list. + RangeType _rangeType = NoRangeInfo; + QVariantList _rangeValues; ///< double values which indicate range setpoints + QVariantList _rangeColors; ///< QColor + QVariantList _rangeIcons; ///< QString resource name + QVariantList _rangeOpacities; /// double opacity value + + // These are user facing string for the various enums. + static const QStringList _rangeTypeNames; + + static const char* _vehicleFactGroupName; +}; + +QML_DECLARE_TYPE(InstrumentValueData) + +Q_DECLARE_METATYPE(InstrumentValueData::RangeType) diff --git a/src/FlightMap/Widgets/InstrumentValueEditDialog.qml b/src/QmlControls/InstrumentValueEditDialog.qml similarity index 68% rename from src/FlightMap/Widgets/InstrumentValueEditDialog.qml rename to src/QmlControls/InstrumentValueEditDialog.qml index 1d6f119101785318198405a1b7a8e2331cf5d358..81382c69776b03a753c2ee7c9830134a15d9a3b6 100644 --- a/src/FlightMap/Widgets/InstrumentValueEditDialog.qml +++ b/src/QmlControls/InstrumentValueEditDialog.qml @@ -12,6 +12,7 @@ import QtQuick.Dialogs 1.3 import QtQuick.Layouts 1.2 import QtQuick.Controls 2.5 +import QGroundControl 1.0 import QGroundControl.Controls 1.0 import QGroundControl.ScreenTools 1.0 import QGroundControl.FactSystem 1.0 @@ -24,7 +25,10 @@ QGCPopupDialog { title: qsTr("Value Display") buttons: StandardButton.Close - property var instrumentValue: dialogProperties.instrumentValue + property var instrumentValueData: dialogProperties.instrumentValueData + + QGCPalette { id: qgcPal; colorGroupEnabled: parent.enabled } + QGCPalette { id: qgcPalDisabled; colorGroupEnabled: false } GridLayout { rowSpacing: _margins @@ -34,116 +38,122 @@ QGCPopupDialog { QGCCheckBox { id: valueCheckBox text: qsTr("Value") - checked: instrumentValue.fact + checked: instrumentValueData.fact onClicked: { if (checked) { - instrumentValue.setFact(instrumentValue.factGroupNames[0], instrumentValue.factValueNames[0]) + instrumentValueData.setFact(instrumentValueData.factGroupNames[0], instrumentValueData.factValueNames[0]) } else { - instrumentValue.clearFact() + instrumentValueData.clearFact() } } } QGCComboBox { - model: instrumentValue.factGroupNames + id: factGroupCombo + Layout.fillWidth: true + model: instrumentValueData.factGroupNames sizeToContents: true - enabled: valueCheckBox.enabled - onModelChanged: currentIndex = find(instrumentValue.factGroupName) - Component.onCompleted: currentIndex = find(instrumentValue.factGroupName) + enabled: valueCheckBox.checked + Component.onCompleted: currentIndex = find(instrumentValueData.factGroupName) onActivated: { - instrumentValue.setFact(currentText, "") - instrumentValue.icon = "" - instrumentValue.text = instrumentValue.fact.shortDescription + instrumentValueData.setFact(currentText, "") + instrumentValueData.icon = "" + instrumentValueData.text = instrumentValueData.fact.shortDescription + } + Connections { + target: instrumentValueData + onFactGroupNameChanged: factGroupCombo.currentIndex = factGroupCombo.find(instrumentValueData.factGroupName) } } QGCComboBox { - model: instrumentValue.factValueNames + id: factNamesCombo + Layout.fillWidth: true + model: instrumentValueData.factValueNames sizeToContents: true - enabled: valueCheckBox.enabled - onModelChanged: currentIndex = instrumentValue.fact ? find(instrumentValue.factName) : -1 - Component.onCompleted: currentIndex = instrumentValue.fact ? find(instrumentValue.factName) : -1 + enabled: valueCheckBox.checked + Component.onCompleted: currentIndex = find(instrumentValueData.factName) onActivated: { - instrumentValue.setFact(instrumentValue.factGroupName, currentText) - instrumentValue.icon = "" - instrumentValue.text = instrumentValue.fact.shortDescription + instrumentValueData.setFact(instrumentValueData.factGroupName, currentText) + instrumentValueData.icon = "" + instrumentValueData.text = instrumentValueData.fact.shortDescription + } + Connections { + target: instrumentValueData + onFactNameChanged: factNamesCombo.currentIndex = factNamesCombo.find(instrumentValueData.factName) } } QGCRadioButton { - id: iconCheckBox + id: iconRadio text: qsTr("Icon") - Component.onCompleted: checked = instrumentValue.icon != "" + Component.onCompleted: checked = instrumentValueData.icon != "" onClicked: { - instrumentValue.text = "" - instrumentValue.icon = instrumentValue.iconNames[0] - var updateFunction = function(icon){ instrumentValue.icon = icon } - mainWindow.showPopupDialog(iconPickerDialog, { iconNames: instrumentValue.iconNames, icon: instrumentValue.icon, updateIconFunction: updateFunction }) + instrumentValueData.text = "" + instrumentValueData.icon = instrumentValueData.iconNames[0] + var updateFunction = function(icon){ instrumentValueData.icon = icon } + mainWindow.showPopupDialog(iconPickerDialog, { iconNames: instrumentValueData.instrumentValueArea.iconNames, icon: instrumentValueData.icon, updateIconFunction: updateFunction }) } } QGCColoredImage { Layout.alignment: Qt.AlignHCenter - height: labelPositionCombo.height + height: ScreenTools.implicitComboBoxHeight width: height - source: "/InstrumentValueIcons/" + (instrumentValue.icon ? instrumentValue.icon : instrumentValue.iconNames[0]) + source: "/InstrumentValueIcons/" + (instrumentValueData.icon ? instrumentValueData.icon : instrumentValueData.instrumentValueArea.iconNames[0]) sourceSize.height: height fillMode: Image.PreserveAspectFit mipmap: true smooth: true color: enabled ? qgcPal.text : qgcPalDisabled.text - enabled: iconCheckBox.checked + enabled: iconRadio.checked MouseArea { anchors.fill: parent onClicked: { - var updateFunction = function(icon){ instrumentValue.icon = icon } - mainWindow.showPopupDialog(iconPickerDialog, { iconNames: instrumentValue.iconNames, icon: instrumentValue.icon, updateIconFunction: updateFunction }) + var updateFunction = function(icon){ instrumentValueData.icon = icon } + mainWindow.showPopupDialog(iconPickerDialog, { iconNames: instrumentValueData.instrumentValueArea.iconNames, icon: instrumentValueData.icon, updateIconFunction: updateFunction }) } } } - QGCComboBox { - id: labelPositionCombo - model: instrumentValue.labelPositionNames - currentIndex: instrumentValue.labelPosition - sizeToContents: true - onActivated: instrumentValue.lanelPosition = index - enabled: iconCheckBox.checked - } + Item { height: 1; width: 1 } QGCRadioButton { - id: labelCheckBox + id: textRadio text: qsTr("Text") - Component.onCompleted: checked = instrumentValue.text != "" + Component.onCompleted: checked = instrumentValueData.icon == "" onClicked: { - instrumentValue.icon = "" - instrumentValue.text = instrumentValue.fact ? instrumentValue.fact.shortDescription : qsTr("Label") + instrumentValueData.icon = "" + instrumentValueData.text = instrumentValueData.fact ? instrumentValueData.fact.shortDescription : qsTr("Label") } } QGCTextField { - id: labelTextField - Layout.fillWidth: true - Layout.columnSpan: 2 - text: instrumentValue.text - enabled: labelCheckBox.checked + id: labelTextField + Layout.fillWidth: true + Layout.columnSpan: 2 + Layout.preferredWidth: ScreenTools.defaultFontPixelWidth * 10 + text: instrumentValueData.text + enabled: textRadio.checked + onEditingFinished: instrumentValueData.text = text } QGCLabel { text: qsTr("Size") } QGCComboBox { id: fontSizeCombo - model: instrumentValue.fontSizeNames - currentIndex: instrumentValue.fontSize + Layout.fillWidth: true + model: instrumentValueData.instrumentValueArea.fontSizeNames + currentIndex: instrumentValueData.instrumentValueArea.fontSize sizeToContents: true - onActivated: instrumentValue.fontSize = index + onActivated: instrumentValueData.instrumentValueArea.fontSize = index } QGCCheckBox { text: qsTr("Show Units") - checked: instrumentValue.showUnits - onClicked: instrumentValue.showUnits = checked + checked: instrumentValueData.showUnits + onClicked: instrumentValueData.showUnits = checked } QGCLabel { text: qsTr("Range") } @@ -151,10 +161,11 @@ QGCPopupDialog { QGCComboBox { id: rangeTypeCombo Layout.columnSpan: 2 - model: instrumentValue.rangeTypeNames - currentIndex: instrumentValue.rangeType + Layout.fillWidth: true + model: instrumentValueData.rangeTypeNames + currentIndex: instrumentValueData.rangeType sizeToContents: true - onActivated: instrumentValue.rangeType = index + onActivated: instrumentValueData.rangeType = index } Loader { @@ -164,20 +175,20 @@ QGCPopupDialog { Layout.preferredWidth: item ? item.width : 0 Layout.preferredHeight: item ? item.height : 0 - property var instrumentValue: root.instrumentValue + property var instrumentValueData: root.instrumentValueData function updateSourceComponent() { - switch (instrumentValue.rangeType) { - case InstrumentValue.NoRangeInfo: + switch (instrumentValueData.rangeType) { + case InstrumentValueData.NoRangeInfo: sourceComponent = undefined break - case InstrumentValue.ColorRange: + case InstrumentValueData.ColorRange: sourceComponent = colorRangeDialog break - case InstrumentValue.OpacityRange: + case InstrumentValueData.OpacityRange: sourceComponent = opacityRangeDialog break - case InstrumentValue.IconSelectRange: + case InstrumentValueData.IconSelectRange: sourceComponent = iconRangeDialog break } @@ -186,7 +197,7 @@ QGCPopupDialog { Component.onCompleted: updateSourceComponent() Connections { - target: instrumentValue + target: instrumentValueData onRangeTypeChanged: rangeLoader.updateSourceComponent() } @@ -201,21 +212,21 @@ QGCPopupDialog { height: childrenRect.height function updateRangeValue(index, text) { - var newValues = instrumentValue.rangeValues + var newValues = instrumentValueData.rangeValues newValues[index] = parseFloat(text) - instrumentValue.rangeValues = newValues + instrumentValueData.rangeValues = newValues } function updateColorValue(index, color) { - var newColors = instrumentValue.rangeColors + var newColors = instrumentValueData.rangeColors newColors[index] = color - instrumentValue.rangeColors = newColors + instrumentValueData.rangeColors = newColors } ColorDialog { id: colorPickerDialog modality: Qt.ApplicationModal - currentColor: instrumentValue.rangeColors.length ? instrumentValue.rangeColors[colorIndex] : "white" + currentColor: instrumentValueData.rangeColors.length ? instrumentValueData.rangeColors[colorIndex] : "white" onAccepted: updateColorValue(colorIndex, color) property int colorIndex: 0 @@ -240,13 +251,13 @@ QGCPopupDialog { spacing: _margins Repeater { - model: instrumentValue.rangeValues.length + model: instrumentValueData.rangeValues.length QGCButton { width: ScreenTools.implicitTextFieldHeight height: width text: qsTr("-") - onClicked: instrumentValue.removeRangeValue(index) + onClicked: instrumentValueData.removeRangeValue(index) } } } @@ -256,10 +267,10 @@ QGCPopupDialog { spacing: _margins Repeater { - model: instrumentValue.rangeValues.length + model: instrumentValueData.rangeValues.length QGCTextField { - text: instrumentValue.rangeValues[index] + text: instrumentValueData.rangeValues[index] onEditingFinished: updateRangeValue(index, text) } } @@ -268,12 +279,12 @@ QGCPopupDialog { Column { spacing: _margins Repeater { - model: instrumentValue.rangeColors + model: instrumentValueData.rangeColors QGCCheckBox { height: ScreenTools.implicitTextFieldHeight - checked: instrumentValue.isValidColor(instrumentValue.rangeColors[index]) - onClicked: updateColorValue(index, checked ? "green" : instrumentValue.invalidColor()) + checked: instrumentValueData.isValidColor(instrumentValueData.rangeColors[index]) + onClicked: updateColorValue(index, checked ? "green" : instrumentValueData.invalidColor()) } } } @@ -281,13 +292,13 @@ QGCPopupDialog { Column { spacing: _margins Repeater { - model: instrumentValue.rangeColors + model: instrumentValueData.rangeColors Rectangle { width: ScreenTools.implicitTextFieldHeight height: width border.color: qgcPal.text - color: instrumentValue.isValidColor(modelData) ? modelData : qgcPal.text + color: instrumentValueData.isValidColor(modelData) ? modelData : qgcPal.text MouseArea { anchors.fill: parent @@ -303,7 +314,7 @@ QGCPopupDialog { QGCButton { text: qsTr("Add Row") - onClicked: instrumentValue.addRangeValue() + onClicked: instrumentValueData.addRangeValue() } } } @@ -317,15 +328,15 @@ QGCPopupDialog { height: childrenRect.height function updateRangeValue(index, text) { - var newValues = instrumentValue.rangeValues + var newValues = instrumentValueData.rangeValues newValues[index] = parseFloat(text) - instrumentValue.rangeValues = newValues + instrumentValueData.rangeValues = newValues } function updateIconValue(index, icon) { - var newIcons = instrumentValue.rangeIcons + var newIcons = instrumentValueData.rangeIcons newIcons[index] = icon - instrumentValue.rangeIcons = newIcons + instrumentValueData.rangeIcons = newIcons } Column { @@ -347,13 +358,13 @@ QGCPopupDialog { spacing: _margins Repeater { - model: instrumentValue.rangeValues.length + model: instrumentValueData.rangeValues.length QGCButton { width: ScreenTools.implicitTextFieldHeight height: width text: qsTr("-") - onClicked: instrumentValue.removeRangeValue(index) + onClicked: instrumentValueData.removeRangeValue(index) } } } @@ -363,10 +374,10 @@ QGCPopupDialog { spacing: _margins Repeater { - model: instrumentValue.rangeValues.length + model: instrumentValueData.rangeValues.length QGCTextField { - text: instrumentValue.rangeValues[index] + text: instrumentValueData.rangeValues[index] onEditingFinished: updateRangeValue(index, text) } } @@ -376,7 +387,7 @@ QGCPopupDialog { spacing: _margins Repeater { - model: instrumentValue.rangeIcons + model: instrumentValueData.rangeIcons QGCColoredImage { height: ScreenTools.implicitTextFieldHeight @@ -392,7 +403,7 @@ QGCPopupDialog { anchors.fill: parent onClicked: { var updateFunction = function(icon){ updateIconValue(index, icon) } - mainWindow.showPopupDialog(iconPickerDialog, { iconNames: instrumentValue.iconNames, icon: modelData, updateIconFunction: updateFunction }) + mainWindow.showPopupDialog(iconPickerDialog, { iconNames: instrumentValueData.instrumentValueArea.iconNames, icon: modelData, updateIconFunction: updateFunction }) } } } @@ -402,7 +413,7 @@ QGCPopupDialog { QGCButton { text: qsTr("Add Row") - onClicked: instrumentValue.addRangeValue() + onClicked: instrumentValueData.addRangeValue() } } } @@ -416,15 +427,15 @@ QGCPopupDialog { height: childrenRect.height function updateRangeValue(index, text) { - var newValues = instrumentValue.rangeValues + var newValues = instrumentValueData.rangeValues newValues[index] = parseFloat(text) - instrumentValue.rangeValues = newValues + instrumentValueData.rangeValues = newValues } function updateOpacityValue(index, opacity) { - var newOpacities = instrumentValue.rangeOpacities + var newOpacities = instrumentValueData.rangeOpacities newOpacities[index] = opacity - instrumentValue.rangeOpacities = newOpacities + instrumentValueData.rangeOpacities = newOpacities } Column { @@ -446,13 +457,13 @@ QGCPopupDialog { spacing: _margins Repeater { - model: instrumentValue.rangeValues.length + model: instrumentValueData.rangeValues.length QGCButton { width: ScreenTools.implicitTextFieldHeight height: width text: qsTr("-") - onClicked: instrumentValue.removeRangeValue(index) + onClicked: instrumentValueData.removeRangeValue(index) } } } @@ -462,7 +473,7 @@ QGCPopupDialog { spacing: _margins Repeater { - model: instrumentValue.rangeValues + model: instrumentValueData.rangeValues QGCTextField { text: modelData @@ -475,7 +486,7 @@ QGCPopupDialog { spacing: _margins Repeater { - model: instrumentValue.rangeOpacities + model: instrumentValueData.rangeOpacities QGCTextField { text: modelData @@ -487,7 +498,7 @@ QGCPopupDialog { QGCButton { text: qsTr("Add Row") - onClicked: instrumentValue.addRangeValue() + onClicked: instrumentValueData.addRangeValue() } } } diff --git a/src/QmlControls/QGCComboBox.qml b/src/QmlControls/QGCComboBox.qml index 10e21069c8326f80476ef31460a9d469c9c18a28..c7295ece3af25148b8a17cab72f4c0df43d62bd7 100644 --- a/src/QmlControls/QGCComboBox.qml +++ b/src/QmlControls/QGCComboBox.qml @@ -125,8 +125,7 @@ T.ComboBox { implicitWidth: ScreenTools.implicitComboBoxWidth implicitHeight: ScreenTools.implicitComboBoxHeight color: _qgcPal.window - border.width: enabled ? 1 : 0 - border.color: "#999" + border.color: _qgcPal.text } popup: T.Popup { diff --git a/src/QmlControls/QGroundControl/Controls/qmldir b/src/QmlControls/QGroundControl/Controls/qmldir index 469d041c8c226cc88114b3483531be539aab01bd..4d38076abf1008e25f58dc6d5c2d0288a3b934a4 100644 --- a/src/QmlControls/QGroundControl/Controls/qmldir +++ b/src/QmlControls/QGroundControl/Controls/qmldir @@ -22,6 +22,9 @@ GeoFenceMapVisuals 1.0 GeoFenceMapVisuals.qml HackFileDialog 1.0 HackFileDialog.qml HeightIndicator 1.0 HeightIndicator.qml IndicatorButton 1.0 IndicatorButton.qml +InstrumentValue 1.0 InstrumentValue.qml +InstrumentValueArea 1.0 InstrumentValueArea.qml +InstrumentValueEditDialog 1.0 InstrumentValueEditDialog.qml JoystickThumbPad 1.0 JoystickThumbPad.qml KMLOrSHPFileDialog 1.0 KMLOrSHPFileDialog.qml LogReplayStatusBar 1.0 LogReplayStatusBar.qml diff --git a/src/QmlControls/QGroundControl/FlightMap/qmldir b/src/QmlControls/QGroundControl/FlightMap/qmldir index f04544e4feb045fffd35cbdcf25e454caca8d890..543a52608c82e8033afed39efbcc0e0c7183ec7e 100644 --- a/src/QmlControls/QGroundControl/FlightMap/qmldir +++ b/src/QmlControls/QGroundControl/FlightMap/qmldir @@ -9,8 +9,6 @@ CenterMapDropButton 1.0 CenterMapDropButton.qml CenterMapDropPanel 1.0 CenterMapDropPanel.qml CompassRing 1.0 CompassRing.qml InstrumentSwipeView 1.0 InstrumentSwipeView.qml -InstrumentValue 1.0 InstrumentValue.qml -InstrumentValueEditDialog 1.0 InstrumentValueEditDialog.qml MapFitFunctions 1.0 MapFitFunctions.qml MapLineArrow 1.0 MapLineArrow.qml MapScale 1.0 MapScale.qml diff --git a/src/api/QGCCorePlugin.cc b/src/api/QGCCorePlugin.cc index cf9b3df364f23bd9b93e174664dcd37e7770b002..9c994b18d2b855f58364259a7e64744bec153695 100644 --- a/src/api/QGCCorePlugin.cc +++ b/src/api/QGCCorePlugin.cc @@ -22,7 +22,8 @@ #endif #include "QGCLoggingCategory.h" #include "QGCCameraManager.h" -#include "ValuesWidgetController.h" +#include "InstrumentValueArea.h" +#include "InstrumentValueData.h" #include #include @@ -407,41 +408,31 @@ QString QGCCorePlugin::showAdvancedUIMessage() const "Are you sure you want to enable Advanced Mode?"); } -QmlObjectListModel* QGCCorePlugin::valuesWidgetDefaultSettings(ValuesWidgetController* newParentController) +void QGCCorePlugin::instrumentValueAreaCreateDefaultSettings(const QString& defaultSettingsGroup) { - ValuesWidgetController controller(true /* forDefaultSettingsCreation */); - - // We don't want these to get written out to settings. This way if the user doesn't modify them - // they will get new changes to default settings from newer builds automatically on next run. - controller.setPreventSaveSettings(true); - - QmlObjectListModel* columnModel = controller.appendRow(); - InstrumentValue* colValue = columnModel->value(0); - colValue->setFact("Vehicle", "AltitudeRelative"); - colValue->setText(colValue->fact()->shortDescription()); - colValue->setShowUnits(true); - colValue->setFontSize(InstrumentValue::LargeFontSize); - - columnModel = controller.appendRow(); - colValue = columnModel->value(0); - colValue->setFact("Vehicle", "GroundSpeed"); - colValue->setText(colValue->fact()->shortDescription()); - colValue->setShowUnits(true); - colValue->setFontSize(InstrumentValue::DefaultFontSize); - - columnModel = controller.appendRow(); - colValue = columnModel->value(0); - colValue->setFact("Vehicle", "FlightTime"); - colValue->setText(colValue->fact()->shortDescription()); - colValue->setShowUnits(false); - colValue->setFontSize(InstrumentValue::DefaultFontSize); - - controller.setPreventSaveSettings(false); - - // Caller takes ownership - controller.setValuesModelParentController(newParentController); - - return controller.valuesModel(); + if (defaultSettingsGroup == InstrumentValueArea::valuePageDefaultSettingsGroup) { + InstrumentValueArea instrumentValueArea(defaultSettingsGroup); + + instrumentValueArea.setFontSize(InstrumentValueArea::LargeFontSize); + + QmlObjectListModel* columnModel = instrumentValueArea.appendRow(); + InstrumentValueData* colValue = columnModel->value(0); + colValue->setFact("Vehicle", "AltitudeRelative"); + colValue->setText(colValue->fact()->shortDescription()); + colValue->setShowUnits(true); + + columnModel = instrumentValueArea.appendRow(); + colValue = columnModel->value(0); + colValue->setFact("Vehicle", "GroundSpeed"); + colValue->setText(colValue->fact()->shortDescription()); + colValue->setShowUnits(true); + + columnModel = instrumentValueArea.appendRow(); + colValue = columnModel->value(0); + colValue->setFact("Vehicle", "FlightTime"); + colValue->setText(colValue->fact()->shortDescription()); + colValue->setShowUnits(false); + } } QQmlApplicationEngine* QGCCorePlugin::createRootWindow(QObject *parent) diff --git a/src/api/QGCCorePlugin.h b/src/api/QGCCorePlugin.h index 2eba39afc295995f711638a9c2bafae0006539c3..772862bdf97efb6f0c1dc298da433d6a481a0125 100644 --- a/src/api/QGCCorePlugin.h +++ b/src/api/QGCCorePlugin.h @@ -37,7 +37,7 @@ class PlanMasterController; class QGCCameraManager; class QGCCameraControl; class QQuickItem; -class ValuesWidgetController; +class InstrumentValueAreaController; class QGCCorePlugin : public QGCTool { @@ -108,9 +108,7 @@ public: /// Allows a plugin to override the specified color name from the palette virtual void paletteOverride(QString colorName, QGCPalette::PaletteColorInfo_t& colorInfo); - /// Return the default Intrument Value model for the Values Widget. The returned model will be - /// re-parented to parentController for ownership. - virtual QmlObjectListModel* valuesWidgetDefaultSettings(ValuesWidgetController* newParentController); + virtual void instrumentValueAreaCreateDefaultSettings(const QString& defaultSettingsGroup); /// Allows the plugin to override the creation of the root (native) window. virtual QQmlApplicationEngine* createRootWindow(QObject* parent);