diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index e0ef70e51d10921e87b330b523fd1e45c099ecff..7d51d491cd1faa1b18ee20bf83aa1c9da7c80348 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -142,6 +142,8 @@ src/QmlControls/QGCMenuSeparator.qml src/QmlControls/QGCMouseArea.qml src/QmlControls/QGCMovableItem.qml + src/QmlControls/QGCPopupDialog.qml + src/QmlControls/QGCPopupDialogContainer.qml src/QmlControls/QGCPipable.qml src/QmlControls/QGCRadioButton.qml src/QmlControls/QGCSlider.qml diff --git a/src/FactSystem/FactGroup.cc b/src/FactSystem/FactGroup.cc index 341d14e903dd623e3d8a266405f02176e2f54dcd..50680dda5f71be247befa8d53c542b7fcf8a2b65 100644 --- a/src/FactSystem/FactGroup.cc +++ b/src/FactSystem/FactGroup.cc @@ -53,8 +53,6 @@ void FactGroup::_setupTimer() Fact* FactGroup::getFact(const QString& name) { - Fact* fact = nullptr; - if (name.contains(".")) { QStringList parts = name.split("."); if (parts.count() != 2) { @@ -71,11 +69,14 @@ Fact* FactGroup::getFact(const QString& name) return factGroup->getFact(parts[1]); } - if (_nameToFactMap.contains(name)) { - fact = _nameToFactMap[name]; + Fact* fact = nullptr; + QString camelCaseName = _camelCase(name); + + if (_nameToFactMap.contains(camelCaseName)) { + fact = _nameToFactMap[camelCaseName]; QQmlEngine::setObjectOwnership(fact, QQmlEngine::CppOwnership); } else { - qWarning() << "Unknown Fact" << name; + qWarning() << "Unknown Fact" << camelCaseName; } return fact; @@ -83,13 +84,14 @@ Fact* FactGroup::getFact(const QString& name) FactGroup* FactGroup::getFactGroup(const QString& name) { - FactGroup* factGroup = nullptr; + FactGroup* factGroup = nullptr; + QString camelCaseName = _camelCase(name); - if (_nameToFactGroupMap.contains(name)) { - factGroup = _nameToFactGroupMap[name]; + if (_nameToFactGroupMap.contains(camelCaseName)) { + factGroup = _nameToFactGroupMap[camelCaseName]; QQmlEngine::setObjectOwnership(factGroup, QQmlEngine::CppOwnership); } else { - qWarning() << "Unknown FactGroup" << name; + qWarning() << "Unknown FactGroup" << camelCaseName; } return factGroup; @@ -142,3 +144,9 @@ void FactGroup::setLiveUpdates(bool liveUpdates) fact->setSendValueChangedSignals(liveUpdates); } } + + +QString FactGroup::_camelCase(const QString& text) +{ + return text[0].toLower() + text.right(text.length() - 1); +} diff --git a/src/FactSystem/FactGroup.h b/src/FactSystem/FactGroup.h index a156c6e212e5fb88b45f564905bf4f70473fd4cc..65d70c8164725d47466598959e29351336d9158d 100644 --- a/src/FactSystem/FactGroup.h +++ b/src/FactSystem/FactGroup.h @@ -44,25 +44,26 @@ public: QStringList factNames(void) const { return _factNames; } QStringList factGroupNames(void) const { return _nameToFactGroupMap.keys(); } -protected: - void _addFact(Fact* fact, const QString& name); - void _addFactGroup(FactGroup* factGroup, const QString& name); - void _loadFromJsonArray(const QJsonArray jsonArray); - - int _updateRateMSecs; ///< Update rate for Fact::valueChanged signals, 0: immediate update - protected slots: virtual void _updateAllValues(void); -private: - void _setupTimer(); - QTimer _updateTimer; - protected: + void _addFact (Fact* fact, const QString& name); + void _addFactGroup (FactGroup* factGroup, const QString& name); + void _loadFromJsonArray (const QJsonArray jsonArray); + + int _updateRateMSecs; ///< Update rate for Fact::valueChanged signals, 0: immediate update + QMap _nameToFactMap; QMap _nameToFactGroupMap; QMap _nameToFactMetaDataMap; QStringList _factNames; + +private: + void _setupTimer (void); + QString _camelCase (const QString& text); + + QTimer _updateTimer; }; #endif diff --git a/src/FlightMap/Widgets/ValuePageWidget.qml b/src/FlightMap/Widgets/ValuePageWidget.qml index 3fc0b95336f8aa4dce84728c87d0a0f2bf5effb6..19320257d2d72d91433e08a4a13bf1b704ee0ca4 100644 --- a/src/FlightMap/Widgets/ValuePageWidget.qml +++ b/src/FlightMap/Widgets/ValuePageWidget.qml @@ -34,8 +34,7 @@ Column { property real _margins: ScreenTools.defaultFontPixelWidth / 2 property int _colMax: 4 property bool _settingsUnlocked: false - property var _valuePickerInstrumentValue: null - property int _valuePickerRowIndex: 0 + property var _valueDialogInstrumentValue: null property var _rgFontSizes: [ ScreenTools.defaultFontPointSize, ScreenTools.smallFontPointSize, ScreenTools.mediumFontPointSize, ScreenTools.largeFontPointSize ] property var _rgFontSizeRatios: [ 1, ScreenTools.smallFontPointRatio, ScreenTools.mediumFontPointRatio, ScreenTools.largeFontPointRatio ] property real _doubleDescent: ScreenTools.defaultFontDescent * 2 @@ -48,6 +47,7 @@ Column { property real _columnButtonsTotalHeight: (_columnButtonHeight * 2) + _columnButtonSpacing QGCPalette { id:qgcPal; colorGroupEnabled: true } + QGCPalette { id:qgcPalDisabled; colorGroupEnabled: false } ValuesWidgetController { id: controller } @@ -79,9 +79,8 @@ Column { property int rowIndex onClicked: { - _valuePickerInstrumentValue = instrumentValue - _valuePickerRowIndex = rowIndex - mainWindow.showComponentDialog(valuePickerDialog, qsTr("Select Value"), mainWindow.showDialogDefaultWidth, StandardButton.Ok) + _valueDialogInstrumentValue = instrumentValue + mainWindow.showPopupDialog(valueDialog, qsTr("Value Display"), StandardButton.Close) } } } @@ -142,7 +141,7 @@ Column { label.x = label.y = 0 } else { // label above value - if (label) { + if (object.label) { label.x = (width - label.width) / 2 label.y = 0 value.y = label.height + smallSpacing @@ -272,242 +271,166 @@ Column { } Component { - id: valuePickerDialog - - QGCViewDialog { - function accept() { - if (factRadioGroup.checkedButton) { - _valuePickerInstrumentValue.setFact(factRadioGroup.checkedButton.radioFactGroupName, factRadioGroup.checkedButton.radioFact.name, labelTextField.text, fontSizeCombo.currentIndex) - } else { - _valuePickerInstrumentValue.clearFact() - } - - hideDialog() - } - - Connections { - target: factRadioGroup - onCheckedButtonChanged: labelTextField.text = factRadioGroup.checkedButton.radioFact.shortDescription - } - - ButtonGroup { id: fontRadioGroup } - - QGCFlickable { - anchors.fill: parent - contentHeight: column.height - flickableDirection: Flickable.VerticalFlick - clip: true - - ColumnLayout { - id: column - anchors.left: parent.left - anchors.right: parent.right - spacing: _margins - - QGCButton { - Layout.fillWidth: true - text: qsTr("Blank Entry") - onClicked: { _valuePickerInstrumentValue.clearFact(); hideDialog() } - } - - RowLayout { - Layout.fillWidth: true - spacing: ScreenTools.defaultFontPixelWidth - - QGCLabel { text: qsTr("Label") } - QGCTextField { - id: labelTextField - Layout.fillWidth: true - text: _valuePickerInstrumentValue.label + id: valueDialog + + QGCPopupDialog { + GridLayout { + rowSpacing: _margins + columnSpacing: _margins + columns: 3 + + QGCCheckBox { + id: valueCheckBox + text: qsTr("Value") + checked: _valueDialogInstrumentValue.fact + onClicked: { + if (checked) { + _valueDialogInstrumentValue.setFact(_valueDialogInstrumentValue.factGroupNames[0], _valueDialogInstrumentValue.factValueNames[0]) + } else { + _valueDialogInstrumentValue.clearFact() } } + } - RowLayout { - spacing: ScreenTools.defaultFontPixelWidth - - QGCLabel { text: qsTr("Font Size") } - QGCComboBox { - id: fontSizeCombo - model: _valuePickerInstrumentValue.fontSizeNames - currentIndex: _valuePickerInstrumentValue.fontSize - sizeToContents: true - onActivated: _valuePickerInstrumentValue.fontSize = index - } - QGCCheckBox { - text: qsTr("Show Units") - checked: _valuePickerInstrumentValue.showUnits - onClicked: _valuePickerInstrumentValue.showUnits = checked - } - } - - RowLayout { - spacing: ScreenTools.defaultFontPixelWidth - - QGCLabel { text: qsTr("Icon") } - - Rectangle { - height: iconPositionCombo.height - width: noIconLabel.width + ScreenTools.defaultFontPixelWidth * 2 - color: qgcPal.window - border.color: qgcPal.text - visible: !_valuePickerInstrumentValue.icon - - QGCLabel { - id: noIconLabel - anchors.centerIn: parent - text: qsTr("No Icon") - } - } - - QGCColoredImage { - height: iconPositionCombo.height - width: height - source: _valuePickerInstrumentValue.icon ? "/InstrumentValueIcons/" + _valuePickerInstrumentValue.icon : "" - sourceSize.height: height - fillMode: Image.PreserveAspectFit - mipmap: true - smooth: true - color: qgcPal.text - visible: _valuePickerInstrumentValue.icon - } - - QGCComboBox { - id: iconPositionCombo - model: _valuePickerInstrumentValue.iconPositionNames - currentIndex: _valuePickerInstrumentValue.iconPosition - sizeToContents: true - onActivated: _valuePickerInstrumentValue.iconPosition = index - } + QGCComboBox { + model: _valueDialogInstrumentValue.factGroupNames + sizeToContents: true + enabled: valueCheckBox.enabled + onModelChanged: currentIndex = find(_valueDialogInstrumentValue.factGroupName) + Component.onCompleted: currentIndex = find(_valueDialogInstrumentValue.factGroupName) + onActivated: { + _valueDialogInstrumentValue.setFact(currentText, "") + _valueDialogInstrumentValue.icon = "" + _valueDialogInstrumentValue.label = _valueDialogInstrumentValue.fact.shortDescription } + } - SectionHeader { - id: iconListHeader - Layout.fillWidth: true - text: qsTr("Icons") - checked: false + QGCComboBox { + model: _valueDialogInstrumentValue.factValueNames + sizeToContents: true + enabled: valueCheckBox.enabled + onModelChanged: currentIndex = _valueDialogInstrumentValue.fact ? find(_valueDialogInstrumentValue.factName) : -1 + Component.onCompleted: currentIndex = _valueDialogInstrumentValue.fact ? find(_valueDialogInstrumentValue.factName) : -1 + onActivated: { + _valueDialogInstrumentValue.setFact(_valueDialogInstrumentValue.factGroupName, currentText) + _valueDialogInstrumentValue.icon = "" + _valueDialogInstrumentValue.label = _valueDialogInstrumentValue.fact.shortDescription } + } - Item { width: 1; height: 1 } - - Loader { - Layout.fillWidth: true - sourceComponent: iconListHeader.checked ? iconList : undefined - visible: iconListHeader.checked + QGCRadioButton { + id: iconCheckBox + text: qsTr("Icon") + Component.onCompleted: checked = _valueDialogInstrumentValue.icon != "" + onClicked: { + _valueDialogInstrumentValue.label = "" + _valueDialogInstrumentValue.icon = _valueDialogInstrumentValue.iconNames[0] + mainWindow.showPopupDialog(iconDialog, qsTr("Select Icon"), StandardButton.Close) } + } - Loader { - Layout.fillWidth: true - sourceComponent: factGroupList - - property var factGroup: _activeVehicle - property string factGroupName: "Vehicle" + QGCColoredImage { + Layout.alignment: Qt.AlignHCenter + height: iconPositionCombo.height + width: height + source: "/InstrumentValueIcons/" + (_valueDialogInstrumentValue.icon ? _valueDialogInstrumentValue.icon : _valueDialogInstrumentValue.iconNames[0]) + sourceSize.height: height + fillMode: Image.PreserveAspectFit + mipmap: true + smooth: true + color: enabled ? qgcPal.text : qgcPalDisabled.text + enabled: iconCheckBox.checked + + MouseArea { + anchors.fill: parent + onClicked: mainWindow.showPopupDialog(iconDialog, qsTr("Select Icon"), StandardButton.Close) } + } - Repeater { - model: _activeVehicle.factGroupNames - - Loader { - Layout.fillWidth: true - sourceComponent: factGroupList + QGCComboBox { + id: iconPositionCombo + model: _valueDialogInstrumentValue.iconPositionNames + currentIndex: _valueDialogInstrumentValue.iconPosition + sizeToContents: true + onActivated: _valueDialogInstrumentValue.iconPosition = index + enabled: iconCheckBox.checked + } - property var factGroup: _activeVehicle.getFactGroup(modelData) - property string factGroupName: modelData - } + QGCRadioButton { + id: labelCheckBox + text: qsTr("Label") + Component.onCompleted: checked = _valueDialogInstrumentValue.label != "" + onClicked: { + _valueDialogInstrumentValue.icon = "" + _valueDialogInstrumentValue.label = _valueDialogInstrumentValue.fact ? _valueDialogInstrumentValue.fact.shortDescription : qsTr("Label") } } - } - } - } - Component { - id: iconList - - Flow { - Rectangle { - height: ScreenTools.minTouchPixels - width: noIconLabel.width + ScreenTools.defaultFontPixelWidth * 2 - color: isNoIcon ? qgcPal.text : qgcPal.window - border.color: isNoIcon ? qgcPal.window : qgcPal.text - - property bool isNoIcon: _valuePickerInstrumentValue.icon === "" - - QGCLabel { - id: noIconLabel - anchors.centerIn: parent - color: parent.isNoIcon ? qgcPal.window : qgcPal.text - text: qsTr("No Icon") + QGCTextField { + id: labelTextField + Layout.fillWidth: true + Layout.columnSpan: 2 + text: _valueDialogInstrumentValue.label + enabled: labelCheckBox.checked } - MouseArea { - anchors.fill: parent - onClicked: _valuePickerInstrumentValue.icon = "" + QGCLabel { text: qsTr("Size") } + + QGCComboBox { + id: fontSizeCombo + Layout.columnSpan: 2 + model: _valueDialogInstrumentValue.fontSizeNames + currentIndex: _valueDialogInstrumentValue.fontSize + sizeToContents: true + onActivated: _valueDialogInstrumentValue.fontSize = index } - } - Repeater { - model: _valuePickerInstrumentValue.iconNames - - Rectangle { - height: ScreenTools.minTouchPixels - width: height - color: currentSelection ? qgcPal.text : qgcPal.window - - property bool currentSelection: _valuePickerInstrumentValue.icon == modelData - - QGCColoredImage { - anchors.centerIn: parent - height: parent.height * 0.75 - width: height - source: "/InstrumentValueIcons/" + modelData - sourceSize.height: height - fillMode: Image.PreserveAspectFit - mipmap: true - smooth: true - color: currentSelection ? qgcPal.window : qgcPal.text - - MouseArea { - anchors.fill: parent - onClicked: _valuePickerInstrumentValue.icon = modelData - } - } + QGCCheckBox { + Layout.columnSpan: 3 + text: qsTr("Show Units") + checked: _valueDialogInstrumentValue.showUnits + onClicked: _valueDialogInstrumentValue.showUnits = checked } } } } Component { - id: factGroupList - - // You must push in the following properties from the Loader - // property var factGroup - // property string factGroupName - - Column { - SectionHeader { - id: header - anchors.left: parent.left - anchors.right: parent.right - text: factGroupName.charAt(0).toUpperCase() + factGroupName.slice(1) - checked: false - } + id: iconDialog - Column { - visible: header.checked + QGCPopupDialog { + GridLayout { + columns: 10 + columnSpacing: 0 + rowSpacing: 0 Repeater { - model: factGroup ? factGroup.factNames : 0 + model: _valueDialogInstrumentValue.iconNames - QGCRadioButton { - text: radioFact.shortDescription - ButtonGroup.group: factRadioGroup - checked: radioFactGroupName == _valuePickerInstrumentValue.factGroupName && radioFact == _valuePickerInstrumentValue.fact + Rectangle { + height: ScreenTools.minTouchPixels + width: height + color: currentSelection ? qgcPal.text : qgcPal.window - property string radioFactGroupName: factGroupName - property var radioFact: factGroup.getFact(modelData) + property bool currentSelection: _valueDialogInstrumentValue.icon == modelData - Component.onCompleted: { - if (checked) { - header.checked = true + QGCColoredImage { + anchors.centerIn: parent + height: parent.height * 0.75 + width: height + source: "/InstrumentValueIcons/" + modelData + sourceSize.height: height + fillMode: Image.PreserveAspectFit + mipmap: true + smooth: true + color: currentSelection ? qgcPal.window : qgcPal.text + + MouseArea { + anchors.fill: parent + onClicked: { + _valueDialogInstrumentValue.icon = modelData + hideDialog() + } } } } diff --git a/src/FlightMap/Widgets/ValuesWidgetController.cc b/src/FlightMap/Widgets/ValuesWidgetController.cc index bf5242721ed4593d209249fd675d42064cedc2f9..9bff80ff894d6cfd1935afb92bdfddd514cc678c 100644 --- a/src/FlightMap/Widgets/ValuesWidgetController.cc +++ b/src/FlightMap/Widgets/ValuesWidgetController.cc @@ -29,6 +29,7 @@ const char* InstrumentValue::_fontSizeKey = "fontSize"; const char* InstrumentValue::_showUnitsKey = "showUnits"; const char* InstrumentValue::_iconKey = "icon"; const char* InstrumentValue::_iconPositionKey = "iconPosition"; +const char* InstrumentValue::_vehicleFactGroupName = "Vehicle"; QStringList InstrumentValue::_iconNames; @@ -234,28 +235,32 @@ void ValuesWidgetController::_loadSettings(void) QStringList largeValues = settings.value(_deprecatedLargeValuesKey).toStringList(); QStringList smallValues = settings.value(_deprecatedSmallValuesKey).toStringList(); - QStringList altitudeProperties = { "altitudeRelative" , "altitudeAMSL" }; + QStringList altitudeProperties = { "AltitudeRelative" , "AltitudeAMSL" }; int rowIndex = -1; int valueCount = 0; QmlObjectListModel* rowModel = nullptr; for (const QString& largeValue: largeValues) { - QStringList parts = largeValue.split("."); + 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(parts[0], parts[1], QString()); + colValue->setFact(factGroupName, factName); colValue->setLabel(colValue->fact()->shortDescription()); colValue->setShowUnits(true); - colValue->setFontSize(altitudeProperties.contains(parts[1]) ? InstrumentValue::LargeFontSize : InstrumentValue::DefaultFontSize); + colValue->setFontSize(altitudeProperties.contains(factName) ? InstrumentValue::LargeFontSize : InstrumentValue::DefaultFontSize); } valueCount = 0; rowModel = nullptr; for (const QString& smallValue: smallValues) { - QStringList parts = smallValue.split("."); + QStringList parts = smallValue.split("."); + QString factGroupName = _pascalCase(parts[0]); + QString factName = _pascalCase(parts[1]); if (!(valueCount++ & 1)) { rowModel = appendRow(false /* addBlankColumn */); @@ -263,7 +268,7 @@ void ValuesWidgetController::_loadSettings(void) } InstrumentValue* colValue = appendColumn(rowIndex); - colValue->setFact(parts[0], parts[1], QString()); + colValue->setFact(factGroupName, factName); colValue->setLabel(colValue->fact()->shortDescription()); colValue->setShowUnits(true); colValue->setFontSize(InstrumentValue::SmallFontSize); @@ -332,6 +337,11 @@ void ValuesWidgetController::setValuesModelParentController(ValuesWidgetControll } } +QString ValuesWidgetController::_pascalCase(const QString& text) +{ + return text[0].toUpper() + text.right(text.length() - 1); +} + InstrumentValue::InstrumentValue(Vehicle* activeVehicle, FontSize fontSize, QmlObjectListModel* rowModel) : QObject (rowModel) , _activeVehicle(activeVehicle) @@ -342,17 +352,27 @@ InstrumentValue::InstrumentValue(Vehicle* activeVehicle, FontSize fontSize, QmlO QDir iconDir(":/InstrumentValueIcons/"); _iconNames = iconDir.entryList(); } + + activeVehicleChanged(_activeVehicle); } void InstrumentValue::activeVehicleChanged(Vehicle* activeVehicle) { _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 == QStringLiteral("Vehicle")) { + if (_factGroupName == _vehicleFactGroupName) { factGroup = _activeVehicle; } else { factGroup = _activeVehicle->getFactGroup(_factGroupName); @@ -365,37 +385,47 @@ void InstrumentValue::activeVehicleChanged(Vehicle* activeVehicle) } } -void InstrumentValue::setFact(QString factGroupName, QString factName, QString label) +void InstrumentValue::setFact(const QString& factGroupName, const QString& factName) { if (_fact) { _fact = nullptr; } FactGroup* factGroup = nullptr; - if (factGroupName == QStringLiteral("Vehicle")) { + 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) { - _fact = factGroup->getFact(factName); + if (factName.isEmpty()) { + nonEmptyFactName = _factValueNames[0]; + } else { + nonEmptyFactName = factName; + } + _fact = factGroup->getFact(nonEmptyFactName); } if (_fact) { - _factName = factName; _factGroupName = factGroupName; - _label = label; + _factName = nonEmptyFactName; } else { _factName.clear(); _factGroupName.clear(); - _label.clear(); } - emit labelChanged(_label); - emit factChanged(_fact); - emit factNameChanged(_factName); - emit factGroupNameChanged(_factGroupName); + emit factChanged (_fact); + emit factNameChanged (_factName); + emit factGroupNameChanged (_factGroupName); + emit factValueNamesChanged (_factValueNames); } void InstrumentValue::_setFontSize(FontSize fontSize) @@ -423,7 +453,7 @@ void InstrumentValue::saveToSettings(QSettings& settings) const { if (_fact) { settings.setValue(_factGroupNameKey, _factGroupName); - settings.setValue(_factNameKey, _fact->name()); + settings.setValue(_factNameKey, _factName); } else { settings.setValue(_factGroupNameKey, ""); settings.setValue(_factNameKey, ""); @@ -446,7 +476,7 @@ void InstrumentValue::readFromSettings(const QSettings& settings) QString factName = settings.value(_factNameKey).toString(); if (!factName.isEmpty()) { - setFact(_factGroupName, factName, _label); + setFact(_factGroupName, factName); } emit factChanged (_fact); diff --git a/src/FlightMap/Widgets/ValuesWidgetController.h b/src/FlightMap/Widgets/ValuesWidgetController.h index 15f86e79f8b9e2b6b77e103762c0d7ba7a02d0b5..60126940fa8776ac56d3e9922fa5932e9f5ceb77 100644 --- a/src/FlightMap/Widgets/ValuesWidgetController.h +++ b/src/FlightMap/Widgets/ValuesWidgetController.h @@ -38,7 +38,10 @@ public: 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 label READ label WRITE setLabel NOTIFY labelChanged) Q_PROPERTY(QString icon READ icon WRITE setIcon NOTIFY iconChanged) ///< If !isEmpty icon will be show instead of label @@ -49,8 +52,8 @@ public: Q_PROPERTY(QStringList fontSizeNames MEMBER _fontSizeNames CONSTANT) Q_PROPERTY(bool showUnits READ showUnits WRITE setShowUnits NOTIFY showUnitsChanged) - Q_INVOKABLE void setFact(QString factGroupName, QString factName, QString label); - Q_INVOKABLE void clearFact(void); + Q_INVOKABLE void setFact(const QString& factGroupName, const QString& factName); + Q_INVOKABLE void clearFact(void); Fact* fact (void) { return _fact; } FontSize fontSize (void) const { return _fontSize; } @@ -76,6 +79,8 @@ signals: void showUnitsChanged (bool showUnits); void iconChanged (const QString& icon); void iconPositionChanged (IconPosition iconPosition); + void factGroupNamesChanged (const QStringList& factGroupNames); + void factValueNamesChanged (const QStringList& factValueNames); private: void _setFontSize (FontSize fontSize); @@ -90,6 +95,8 @@ private: FontSize _fontSize = DefaultFontSize; QString _icon; IconPosition _iconPosition = IconLeft; + QStringList _factGroupNames; + QStringList _factValueNames; static const QStringList _iconPositionNames; static QStringList _iconNames; @@ -102,6 +109,7 @@ private: static const char* _showUnitsKey; static const char* _iconKey; static const char* _iconPositionKey; + static const char* _vehicleFactGroupName; }; Q_DECLARE_METATYPE(InstrumentValue::FontSize) @@ -146,7 +154,7 @@ private: 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; diff --git a/src/QmlControls/QGCPopupDialog.qml b/src/QmlControls/QGCPopupDialog.qml new file mode 100644 index 0000000000000000000000000000000000000000..fa7f8cb01a74da890194b441ab4e02437b14b14e --- /dev/null +++ b/src/QmlControls/QGCPopupDialog.qml @@ -0,0 +1,41 @@ +/**************************************************************************** + * + * (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 + +Item { + width: childrenRect.width + height: childrenRect.height + + signal hideDialog + + Keys.onReleased: { + if (event.key === Qt.Key_Escape) { + reject() + event.accepted = true + } else if (event.key === Qt.Key_Return || event.key === Qt.Key_Enter) { + accept() + event.accepted = true + } + } + + function accept() { + if (acceptAllowed) { + Qt.inputMethod.hide() + hideDialog() + } + } + + function reject() { + if (rejectAllowed) { + Qt.inputMethod.hide() + hideDialog() + } + } +} diff --git a/src/QmlControls/QGCPopupDialogContainer.qml b/src/QmlControls/QGCPopupDialogContainer.qml new file mode 100644 index 0000000000000000000000000000000000000000..4a2b6d665b6a37fb6f438804e8844aff6742a58f --- /dev/null +++ b/src/QmlControls/QGCPopupDialogContainer.qml @@ -0,0 +1,174 @@ +/**************************************************************************** + * + * (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.Controls 2.4 +import QtQuick.Layouts 1.12 +import QtQuick.Dialogs 1.3 + +import QGroundControl 1.0 +import QGroundControl.Controls 1.0 +import QGroundControl.Palette 1.0 +import QGroundControl.ScreenTools 1.0 + +Popup { + anchors.centerIn: parent + width: mainFlickable.width + height: mainFlickable.height + padding: 0 + modal: true + focus: true + + background: Rectangle { + color: QGroundControl.globalPalette.window + } + + property string title + property var buttons + property var dialogComponent + + property real _contentMargin: ScreenTools.defaultFontPixelHeight / 2 + property real _popupDoubleInset: ScreenTools.defaultFontPixelHeight * 2 + property real _maxAvailableWidth: parent.width - _popupDoubleInset + property real _maxAvailableHeight: parent.height - _popupDoubleInset + + Component.onCompleted: setupDialogButtons() + + QGCPalette { id: qgcPal; colorGroupEnabled: parent.enabled } + + function setupDialogButtons() { + acceptButton.visible = false + rejectButton.visible = false + // Accept role buttons + if (buttons & StandardButton.Ok) { + acceptButton.text = qsTr("Ok") + acceptButton.visible = true + } else if (buttons & StandardButton.Open) { + acceptButton.text = qsTr("Open") + acceptButton.visible = true + } else if (buttons & StandardButton.Save) { + acceptButton.text = qsTr("Save") + acceptButton.visible = true + } else if (buttons & StandardButton.Apply) { + acceptButton.text = qsTr("Apply") + acceptButton.visible = true + } else if (buttons & StandardButton.Open) { + acceptButton.text = qsTr("Open") + acceptButton.visible = true + } else if (buttons & StandardButton.SaveAll) { + acceptButton.text = qsTr("Save All") + acceptButton.visible = true + } else if (buttons & StandardButton.Yes) { + acceptButton.text = qsTr("Yes") + acceptButton.visible = true + } else if (buttons & StandardButton.YesToAll) { + acceptButton.text = qsTr("Yes to All") + acceptButton.visible = true + } else if (buttons & StandardButton.Retry) { + acceptButton.text = qsTr("Retry") + acceptButton.visible = true + } else if (buttons & StandardButton.Reset) { + acceptButton.text = qsTr("Reset") + acceptButton.visible = true + } else if (buttons & StandardButton.RestoreToDefaults) { + acceptButton.text = qsTr("Restore to Defaults") + acceptButton.visible = true + } else if (buttons & StandardButton.Ignore) { + acceptButton.text = qsTr("Ignore") + acceptButton.visible = true + } + + // Reject role buttons + if (buttons & StandardButton.Cancel) { + rejectButton.text = qsTr("Cancel") + rejectButton.visible = true + } else if (buttons & StandardButton.Close) { + rejectButton.text = qsTr("Close") + rejectButton.visible = true + } else if (buttons & StandardButton.No) { + rejectButton.text = qsTr("No") + rejectButton.visible = true + } else if (buttons & StandardButton.NoToAll) { + rejectButton.text = qsTr("No to All") + rejectButton.visible = true + } else if (buttons & StandardButton.Abort) { + rejectButton.text = qsTr("Abort") + rejectButton.visible = true + } + + if (rejectButton.visible) { + closePolicy = Popup.NoAutoClose | Popup.CloseOnEscape + } else { + closePolicy = Popup.NoAutoClose + } + } + + Connections { + target: dialogComponentLoader.item + onHideDialog: close() + } + + QGCFlickable { + id: mainFlickable + width: Math.min(mainColumnLayout.width, _maxAvailableWidth) + height: Math.min(mainColumnLayout.height, _maxAvailableHeight) + contentWidth: mainColumnLayout.width + contentHeight: mainColumnLayout.height + + Rectangle { + width: titleRowLayout.width + height: titleRowLayout.height + color: qgcPal.windowShade + } + + ColumnLayout { + id: mainColumnLayout + spacing: _contentMargin + + RowLayout { + id: titleRowLayout + Layout.fillWidth: true + + QGCLabel { + Layout.leftMargin: ScreenTools.defaultFontPixelWidth + Layout.fillWidth: true + text: title + height: parent.height + verticalAlignment: Text.AlignVCenter + } + + QGCButton { + id: rejectButton + onClicked: dialogComponentLoader.item.reject() + } + + QGCButton { + id: acceptButton + primary: true + onClicked: dialogComponentLoader.item.accept() + } + } + + Item { + id: item + width: dialogComponentLoader.width + (_contentMargin * 2) + height: dialogComponentLoader.height + _contentMargin + + Loader { + id: dialogComponentLoader + x: _contentMargin + sourceComponent: dialogComponent + focus: true + property bool acceptAllowed: acceptButton.visible + property bool rejectAllowed: rejectButton.visible + } + } + } + } +} diff --git a/src/QmlControls/QGroundControl/Controls/qmldir b/src/QmlControls/QGroundControl/Controls/qmldir index 33bd6924834dc0c8a9920b7ffd00c01c59ba6c2d..64250fb09f75cfea6a4135e1b510506d5af2719e 100644 --- a/src/QmlControls/QGroundControl/Controls/qmldir +++ b/src/QmlControls/QGroundControl/Controls/qmldir @@ -64,6 +64,8 @@ QGCMouseArea 1.0 QGCMouseArea.qml QGCMovableItem 1.0 QGCMovableItem.qml QGCOptionsComboBox 1.0 QGCOptionsComboBox.qml QGCPipable 1.0 QGCPipable.qml +QGCPopupDialog 1.0 QGCPopupDialog.qml +QGCPopupDialogContainer 1.0 QGCPopupDialogContainer.qml QGCRadioButton 1.0 QGCRadioButton.qml QGCSlider 1.0 QGCSlider.qml QGCSwitch 1.0 QGCSwitch.qml diff --git a/src/api/QGCCorePlugin.cc b/src/api/QGCCorePlugin.cc index ebf4eedde66a1d3a7d1154c01ecc922af5c1f4ac..5e2fb05b242abc3d5444ff0cf02ad83104cbdfcd 100644 --- a/src/api/QGCCorePlugin.cc +++ b/src/api/QGCCorePlugin.cc @@ -417,21 +417,21 @@ QmlObjectListModel* QGCCorePlugin::valuesWidgetDefaultSettings(ValuesWidgetContr QmlObjectListModel* columnModel = controller.appendRow(); InstrumentValue* colValue = columnModel->value(0); - colValue->setFact("Vehicle", "altitudeRelative", QString()); + colValue->setFact("Vehicle", "AltitudeRelative"); colValue->setLabel(colValue->fact()->shortDescription()); colValue->setShowUnits(true); colValue->setFontSize(InstrumentValue::LargeFontSize); columnModel = controller.appendRow(); colValue = columnModel->value(0); - colValue->setFact("Vehicle", "groundSpeed", QString()); + colValue->setFact("Vehicle", "GroundSpeed"); colValue->setLabel(colValue->fact()->shortDescription()); colValue->setShowUnits(true); colValue->setFontSize(InstrumentValue::DefaultFontSize); columnModel = controller.appendRow(); colValue = columnModel->value(0); - colValue->setFact("Vehicle", "flightTime", QString()); + colValue->setFact("Vehicle", "FlightTime"); colValue->setLabel(colValue->fact()->shortDescription()); colValue->setShowUnits(false); colValue->setFontSize(InstrumentValue::DefaultFontSize); diff --git a/src/ui/MainRootWindow.qml b/src/ui/MainRootWindow.qml index c4e16a072765d5e81aef35090cce094f40ba929c..b8edc6cb61840595efd95134a8b44713725d83fb 100644 --- a/src/ui/MainRootWindow.qml +++ b/src/ui/MainRootWindow.qml @@ -223,6 +223,16 @@ ApplicationWindow { } } + function showPopupDialog(component, title, buttons) { + var popup = popupDialogContainterComponent.createObject(mainWindow, { "title": title, "buttons": buttons, "dialogComponent": component}) + popup.open() + } + + Component { + id: popupDialogContainterComponent + QGCPopupDialogContainer { } + } + property bool _forceClose: false function finishCloseProcess() {