diff --git a/qgcresources.qrc b/qgcresources.qrc
index 3b76854..977a849 100644
--- a/qgcresources.qrc
+++ b/qgcresources.qrc
@@ -25,6 +25,8 @@
resources/JoystickBezel.png
resources/JoystickBezelLight.png
resources/land.svg
+ resources/LockClosed.svg
+ resources/LockOpen.svg
resources/notile.png
resources/Pause.svg
resources/pause-mission.svg
diff --git a/resources/LockClosed.svg b/resources/LockClosed.svg
new file mode 100644
index 0000000..600eb24
--- /dev/null
+++ b/resources/LockClosed.svg
@@ -0,0 +1,136 @@
+
+
+
diff --git a/resources/LockOpen.svg b/resources/LockOpen.svg
new file mode 100644
index 0000000..1bed7f6
--- /dev/null
+++ b/resources/LockOpen.svg
@@ -0,0 +1,136 @@
+
+
+
diff --git a/src/FlightMap/Widgets/ValuePageWidget.qml b/src/FlightMap/Widgets/ValuePageWidget.qml
index 944f594..e0db7f7 100644
--- a/src/FlightMap/Widgets/ValuePageWidget.qml
+++ b/src/FlightMap/Widgets/ValuePageWidget.qml
@@ -10,6 +10,8 @@
import QtQuick 2.3
import QtQuick.Dialogs 1.2
import QtQuick.Layouts 1.2
+import QtQuick.Controls 2.5
+import QtQml 2.12
import QGroundControl.Controls 1.0
import QGroundControl.ScreenTools 1.0
@@ -21,23 +23,32 @@ import QGroundControl 1.0
/// Value page for InstrumentPanel PageView
Column {
- id: _largeColumn
+ id: _root
width: pageWidth
- spacing: _margins
+ spacing: ScreenTools.defaultFontPixelHeight / 2
property bool showSettingsIcon: true
-
- property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle ? QGroundControl.multiVehicleManager.activeVehicle : QGroundControl.multiVehicleManager.offlineEditingVehicle
- property real _margins: ScreenTools.defaultFontPixelWidth / 2
+ 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 _valuePickerInstrumentValue: null
+ property int _valuePickerRowIndex: 0
+ property var _rgFontSizes: [ ScreenTools.defaultFontPointSize, ScreenTools.smallFontPointSize, ScreenTools.mediumFontPointSize, ScreenTools.largeFontPointSize ]
+ property real _blankEntryHeight: ScreenTools.defaultFontPixelHeight * 2
+ 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 }
- ValuesWidgetController {
- id: controller
- }
+ ValuesWidgetController { id: controller }
- function showSettings() {
- mainWindow.showComponentDialog(propertyPicker, qsTr("Value Widget Setup"), mainWindow.showDialogDefaultWidth, StandardButton.Ok)
+ function showSettings(settingsUnlocked) {
+ _settingsUnlocked = settingsUnlocked
}
function listContains(list, value) {
@@ -49,88 +60,166 @@ Column {
return false
}
- Repeater {
- model: _activeVehicle ? controller.largeValues : 0
- Loader {
- sourceComponent: fact ? largeValue : undefined
- property Fact fact: _activeVehicle.getFact(modelData.replace("Vehicle.", ""))
- }
- } // Repeater - Large
-
- Flow {
- id: _smallFlow
- width: parent.width
- layoutDirection: Qt.LeftToRight
- spacing: _margins
-
- Repeater {
- model: _activeVehicle ? controller.smallValues : 0
- Loader {
- sourceComponent: fact ? smallValue : undefined
- property Fact fact: _activeVehicle.getFact(modelData.replace("Vehicle.", ""))
- }
- } // Repeater - Small
- } // Flow
+ ButtonGroup { id: factRadioGroup }
Component {
- id: largeValue
+ id: valueItemMouseAreaComponent
- Column {
- width: _largeColumn.width
- property bool largeValue: listContains(controller.altitudeProperties, fact.name)
-
- QGCLabel {
- width: parent.width
- horizontalAlignment: Text.AlignHCenter
- wrapMode: Text.WordWrap
- text: fact.shortDescription + (fact.units ? " (" + fact.units + ")" : "")
- }
- QGCLabel {
- width: parent.width
- horizontalAlignment: Text.AlignHCenter
- font.pointSize: ScreenTools.mediumFontPointSize * (largeValue ? 1.3 : 1.0)
- font.family: largeValue ? ScreenTools.demiboldFontFamily : ScreenTools.normalFontFamily
- fontSizeMode: Text.HorizontalFit
- text: fact.enumOrValueString
+ MouseArea {
+ anchors.centerIn: parent
+ width: parent.width
+ height: _columnButtonsTotalHeight
+ visible: _settingsUnlocked
+
+ property var instrumentValue
+ property int rowIndex
+
+ onClicked: {
+ _valuePickerInstrumentValue = instrumentValue
+ _valuePickerRowIndex = rowIndex
+ mainWindow.showComponentDialog(valuePickerDialog, qsTr("Select Value"), mainWindow.showDialogDefaultWidth, StandardButton.Ok)
}
}
}
- Component {
- id: smallValue
+ Repeater {
+ id: rowRepeater
+ model: controller.valuesModel
Column {
- width: (pageWidth / 2) - (_margins / 2) - 0.1
- clip: true
-
- QGCLabel {
- width: parent.width
- wrapMode: Text.WordWrap
- horizontalAlignment: Text.AlignHCenter
- font.pointSize: ScreenTools.isTinyScreen ? ScreenTools.smallFontPointSize * 0.75 : ScreenTools.smallFontPointSize
- text: fact.shortDescription
- }
- QGCLabel {
- width: parent.width
- horizontalAlignment: Text.AlignHCenter
- fontSizeMode: Text.HorizontalFit
- text: fact.enumOrValueString
- }
- QGCLabel {
- width: parent.width
- horizontalAlignment: Text.AlignHCenter
- font.pointSize: ScreenTools.isTinyScreen ? ScreenTools.smallFontPointSize * 0.75 : ScreenTools.smallFontPointSize
- fontSizeMode: Text.HorizontalFit
- text: fact.units
+ 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
+
+ onItemAdded: valueItemMouseAreaComponent.createObject(item, { "instrumentValue": object.get(index), "rowIndex": index })
+
+ Item {
+ width: columnRepeater.columnWidth
+ height: value.y + value.height
+ anchors.verticalCenter: _settingsUnlocked ? parent.verticalCenter : undefined
+ anchors.bottom: _settingsUnlocked ? undefined : parent.bottom
+
+ QGCLabel {
+ width: columnRepeater.columnWidth
+ height: _columnButtonsTotalHeight
+ font.pointSize: ScreenTools.smallFontPointSize
+ text: _settingsUnlocked ? qsTr("BLANK") : ""
+ horizontalAlignment: Text.AlignHCenter
+ verticalAlignment: Text.AlignVCenter
+ visible: !object.fact
+ }
+
+ QGCLabel {
+ id: label
+ width: columnRepeater.columnWidth
+ font.pointSize: ScreenTools.smallFontPointSize
+ text: object.label.toUpperCase()
+ horizontalAlignment: Text.AlignHCenter
+ visible: object.fact && object.label
+ }
+
+ QGCLabel {
+ id: value
+ anchors.topMargin: label.visible ? 2 : 0
+ anchors.top: label.visible ? label.bottom : parent.top
+ width: columnRepeater.columnWidth
+ font.pointSize: _rgFontSizes[object.fontSize]
+ text: visible ? (object.fact.enumOrValueString + (object.showUnits ? object.fact.units : "")) : ""
+ horizontalAlignment: Text.AlignHCenter
+ visible: object.fact
+ }
+ }
+ } // Repeater - columns
+
+ ColumnLayout {
+ id: columnsButtonsLayout
+ width: _columnButtonWidth
+ spacing: _columnButtonSpacing
+ visible: _settingsUnlocked
+
+ QGCButton {
+ Layout.fillHeight: true
+ Layout.minimumHeight: ScreenTools.minTouchPixels
+ Layout.preferredWidth: parent.width
+ text: qsTr("+")
+ onClicked: controller.appendColumn(rowRepeaterLayout.rowIndex)
+ }
+
+ QGCButton {
+ Layout.fillHeight: true
+ Layout.minimumHeight: ScreenTools.minTouchPixels
+ Layout.preferredWidth: parent.width
+ text: qsTr("-")
+ enabled: index !== 0 || columnRepeater.count !== 1
+ onClicked: controller.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: controller.insertRow(index)
+ }
+
+ QGCButton {
+ Layout.fillWidth: true
+ Layout.preferredHeight: ScreenTools.defaultFontPixelWidth * 2
+ text: qsTr("-")
+ enabled: index !== 0
+ onClicked: controller.deleteRow(index)
+ }
}
}
+ } // Repeater - rows
+
+ QGCButton {
+ anchors.left: parent.left
+ anchors.right: parent.right
+ text: qsTr("Reset To Defaults")
+ visible: _settingsUnlocked
+ onClicked: controller.resetToDefaults()
}
Component {
- id: propertyPicker
+ id: valuePickerDialog
QGCViewDialog {
- id: _propertyPickerDialog
+ 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
@@ -138,39 +227,50 @@ Column {
flickableDirection: Flickable.VerticalFlick
clip: true
- Column {
+ ColumnLayout {
id: column
anchors.left: parent.left
anchors.right: parent.right
spacing: _margins
- /*
- Leaving this here for now just in case
- FactCheckBox {
- text: qsTr("Show large compass")
- fact: _showLargeCompass
- visible: _showLargeCompass.visible
+ RowLayout {
+ Layout.fillWidth: true
+ spacing: ScreenTools.defaultFontPixelWidth
+
+ QGCLabel { text: qsTr("Label") }
+ QGCTextField {
+ id: labelTextField
+ Layout.fillWidth: true
+ text: _valuePickerInstrumentValue.label
+ }
+ }
- property Fact _showLargeCompass: QGroundControl.settingsManager.appSettings.showLargeCompass
+ RowLayout {
+ spacing: ScreenTools.defaultFontPixelWidth
+
+ QGCLabel { text: qsTr("Font Size (for whole row)") }
+ QGCComboBox {
+ id: fontSizeCombo
+ model: [ qsTr("Default"), qsTr("Small"), qsTr("Medium"), qsTr("Large") ]
+ currentIndex: _valuePickerInstrumentValue.fontSize
+ sizeToContents: true
+ onActivated: _valuePickerInstrumentValue.fontSize = index
+ }
}
- */
- Item {
- width: 1
- height: _margins
+ QGCCheckBox {
+ text: qsTr("Show Units")
+ checked: _valuePickerInstrumentValue.showUnits
+ onClicked: _valuePickerInstrumentValue.showUnits = checked
}
- QGCLabel {
- id: _label
- anchors.left: parent.left
- anchors.right: parent.right
- wrapMode: Text.WordWrap
- text: qsTr("Select the values you want to display:")
+ QGCButton {
+ text: qsTr("Blank Entry")
+ onClicked: { _valuePickerInstrumentValue.clearFact(); hideDialog() }
}
Loader {
- anchors.left: parent.left
- anchors.right: parent.right
+ Layout.fillWidth: true
sourceComponent: factGroupList
property var factGroup: _activeVehicle
@@ -181,14 +281,12 @@ Column {
model: _activeVehicle.factGroupNames
Loader {
- anchors.left: parent.left
- anchors.right: parent.right
+ Layout.fillWidth: true
sourceComponent: factGroupList
property var factGroup: _activeVehicle.getFactGroup(modelData)
property string factGroupName: modelData
}
-
}
}
}
@@ -203,8 +301,6 @@ Column {
// property string factGroupName
Column {
- spacing: _margins
-
SectionHeader {
id: header
anchors.left: parent.left
@@ -214,78 +310,23 @@ Column {
}
Column {
- spacing: _margins
- visible: header.checked
+ visible: header.checked
Repeater {
model: factGroup ? factGroup.factNames : 0
- RowLayout {
- spacing: _margins
- visible: factGroup.getFact(modelData).shortDescription !== ""
-
- property string propertyName: factGroupName + "." + modelData
+ QGCRadioButton {
+ text: radioFact.shortDescription
+ ButtonGroup.group: factRadioGroup
+ checked: radioFactGroupName == _valuePickerInstrumentValue.factGroupName && radioFact == _valuePickerInstrumentValue.fact
- function removeFromList(list, value) {
- var newList = []
- for (var i=0; i
-const char* ValuesWidgetController::_groupKey = "ValuesWidget";
-const char* ValuesWidgetController::_largeValuesKey = "large";
-const char* ValuesWidgetController::_smallValuesKey = "small";
+const char* ValuesWidgetController::_groupKey = "ValuesWidget2";
+const char* ValuesWidgetController::_rowsKey = "rows";
+const char* ValuesWidgetController::_columnsKey = "columns";
-ValuesWidgetController::ValuesWidgetController(void)
+const char* ValuesWidgetController::_deprecatedGroupKey = "ValuesWidget";
+const char* ValuesWidgetController::_deprecatedLargeValuesKey = "large";
+const char* ValuesWidgetController::_deprecatedSmallValuesKey = "small";
+
+const char* InstrumentValue::_factGroupNameKey = "groupName";
+const char* InstrumentValue::_factNameKey = "factName";
+const char* InstrumentValue::_labelKey = "label";
+const char* InstrumentValue::_fontSizeKey = "fontSize";
+const char* InstrumentValue::_showUnitsKey = "showUnits";
+
+ValuesWidgetController::ValuesWidgetController(bool forDefaultSettingsCreation)
+ : _valuesModel(new QmlObjectListModel(this))
{
QSettings settings;
settings.beginGroup(_groupKey);
- QStringList largeDefaults, smallDefaults;
- qgcApp()->toolbox()->corePlugin()->valuesWidgetDefaultSettings(largeDefaults, smallDefaults);
+ _multiVehicleMgr = qgcApp()->toolbox()->multiVehicleManager();
+ connect(_multiVehicleMgr, &MultiVehicleManager::activeVehicleChanged, this, &ValuesWidgetController::_activeVehicleChanged);
+
+ if (!forDefaultSettingsCreation) {
+ _loadSettings();
+ }
+}
+
+InstrumentValue* ValuesWidgetController::_createNewInstrumentValueWorker(Vehicle* activeVehicle, int fontSize, QmlObjectListModel* rowModel)
+{
+ InstrumentValue* newValue = new InstrumentValue(activeVehicle, fontSize, rowModel);
+
+ connect(newValue, &InstrumentValue::factChanged, this, &ValuesWidgetController::_saveSettings);
+ connect(newValue, &InstrumentValue::factGroupNameChanged, this, &ValuesWidgetController::_saveSettings);
+ connect(newValue, &InstrumentValue::labelChanged, this, &ValuesWidgetController::_saveSettings);
+ connect(newValue, &InstrumentValue::fontSizeChanged, this, &ValuesWidgetController::_saveSettings);
+ connect(newValue, &InstrumentValue::showUnitsChanged, this, &ValuesWidgetController::_saveSettings);
+
+ return newValue;
+}
- _largeValues = settings.value(_largeValuesKey, largeDefaults).toStringList();
- _smallValues = settings.value(_smallValuesKey, smallDefaults).toStringList();
- _altitudeProperties << "altitudeRelative" << "altitudeAMSL";
+InstrumentValue* ValuesWidgetController::appendColumn(int rowIndex)
+{
+ InstrumentValue* newValue = nullptr;
- // Keep back compat for removed WGS84 value
- if (_largeValues.contains ("Vehicle.altitudeWGS84")) {
- setLargeValues(_largeValues.replaceInStrings("Vehicle.altitudeWGS84", "Vehicle.altitudeRelative"));
+ if (rowIndex >= 0 && rowIndex < _valuesModel->count()) {
+ QmlObjectListModel* row = _valuesModel->value(rowIndex);
+ int fontSize = InstrumentValue::DefaultFontSize;
+ if (row->count()) {
+ fontSize = row->value(0)->fontSize();
+ }
+ newValue = _createNewInstrumentValueWorker(_currentActiveVehicle(), fontSize, row);
+ row->append(newValue);
}
- if (_smallValues.contains ("Vehicle.altitudeWGS84")) {
- setSmallValues(_largeValues.replaceInStrings("Vehicle.altitudeWGS84", "Vehicle.altitudeRelative"));
+ _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();
}
-void ValuesWidgetController::setLargeValues(const QStringList& values)
+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.setValue(_largeValuesKey, values);
+ 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(".");
+
+ rowModel = appendRow(false /* addBlankColumn */);
+ rowIndex++;
+
+ InstrumentValue* colValue = appendColumn(rowIndex);
+ colValue->setFact(parts[0], parts[1], QString());
+ colValue->setLabel(colValue->fact()->shortDescription());
+ colValue->setShowUnits(true);
+ colValue->setFontSize(altitudeProperties.contains(parts[1]) ? InstrumentValue::LargeFontSize : InstrumentValue::DefaultFontSize);
+ }
- _largeValues = values;
- emit largeValuesChanged(values);
+ valueCount = 0;
+ rowModel = nullptr;
+ for (const QString& smallValue: smallValues) {
+ QStringList parts = smallValue.split(".");
+
+ if (!(valueCount++ & 1)) {
+ rowModel = appendRow(false /* addBlankColumn */);
+ rowIndex++;
+ }
+
+ InstrumentValue* colValue = appendColumn(rowIndex);
+ colValue->setFact(parts[0], parts[1], QString());
+ colValue->setLabel(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::setSmallValues(const QStringList& values)
+void ValuesWidgetController::resetToDefaults(void)
{
QSettings settings;
settings.beginGroup(_groupKey);
- settings.setValue(_smallValuesKey, values);
+ settings.remove("");
+
+ _loadSettings();
+}
+
+void ValuesWidgetController::setPreventSaveSettings(bool preventSaveSettings)
+{
+ _preventSaveSettings = preventSaveSettings;
+}
+
+InstrumentValue::InstrumentValue(Vehicle* activeVehicle, int fontSize, QmlObjectListModel* rowModel)
+ : QObject (rowModel)
+ , _activeVehicle(activeVehicle)
+ , _rowModel (rowModel)
+ , _fontSize (fontSize)
+{
+
+}
+
+void InstrumentValue::activeVehicleChanged(Vehicle* activeVehicle)
+{
+ _activeVehicle = activeVehicle;
+
+ if (_fact) {
+ _fact = nullptr;
+
+ FactGroup* factGroup = nullptr;
+ QString factName;
+ if (_factGroupName == QStringLiteral("Vehicle")) {
+ factGroup = _activeVehicle;
+ } else {
+ factGroup = _activeVehicle->getFactGroup(_factGroupName);
+ }
+
+ if (factGroup) {
+ _fact = factGroup->getFact(factName);
+ }
+ emit factChanged(_fact);
+ }
+}
+
+void InstrumentValue::setFact(QString factGroupName, QString factName, QString label)
+{
+ if (_fact) {
+ _fact = nullptr;
+ }
+
+ FactGroup* factGroup = nullptr;
+ if (factGroupName == QStringLiteral("Vehicle")) {
+ factGroup = _activeVehicle;
+ } else {
+ factGroup = _activeVehicle->getFactGroup(factGroupName);
+ }
+
+ if (factGroup) {
+ _fact = factGroup->getFact(factName);
+ }
+
+ if (_fact) {
+ _factGroupName = factGroupName;
+ _label = label;
+ } else {
+ _factGroupName.clear();
+ _label.clear();
+ }
+
+ emit labelChanged(_label);
+ emit factChanged(_fact);
+ emit factGroupNameChanged(_factGroupName);
+}
+
+void InstrumentValue::_setFontSize(int fontSize)
+{
+ if (fontSize != _fontSize) {
+ _fontSize = fontSize;
+ emit fontSizeChanged(fontSize);
+ }
+}
+
+void InstrumentValue::setFontSize(int 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
+{
+ if (_fact) {
+ settings.setValue(_factGroupNameKey, _factGroupName);
+ settings.setValue(_factNameKey, _fact->name());
+ } else {
+ settings.setValue(_factGroupNameKey, "");
+ settings.setValue(_factNameKey, "");
+ }
+ settings.setValue(_labelKey, _label);
+ settings.setValue(_fontSizeKey, _fontSize);
+ settings.setValue(_showUnitsKey, _showUnits);
+}
+
+void InstrumentValue::readFromSettings(const QSettings& settings)
+{
+ _factGroupName = settings.value(_factGroupNameKey).toString();
+ _label = settings.value(_labelKey).toString();
+ _fontSize = settings.value(_fontSizeKey).toInt();
+ _showUnits = settings.value(_showUnitsKey).toBool();
+
+ QString factName = settings.value(_factNameKey).toString();
+ if (!factName.isEmpty()) {
+ setFact(_factGroupName, factName, _label);
+ }
+
+ emit factChanged (_fact);
+ emit factGroupNameChanged (_factGroupName);
+ emit labelChanged (_label);
+ emit fontSizeChanged (_fontSize);
+ emit showUnitsChanged (_showUnits);
+}
+
+void InstrumentValue::setLabel(const QString& label)
+{
+ if (label != _label) {
+ _label = label;
+ emit labelChanged(label);
+ }
+}
+
+void InstrumentValue::setShowUnits(bool showUnits)
+{
+ if (showUnits != _showUnits) {
+ _showUnits = showUnits;
+ emit showUnitsChanged(showUnits);
+ }
+}
+
+void InstrumentValue::clearFact(void)
+{
+ _fact = nullptr;
+ _factGroupName.clear();
+ _label.clear();
+ _showUnits = true;
- _smallValues = values;
- emit smallValuesChanged(values);
+ emit factChanged (_fact);
+ emit factGroupNameChanged (_factGroupName);
+ emit labelChanged (_label);
+ emit showUnitsChanged (_showUnits);
}
diff --git a/src/FlightMap/Widgets/ValuesWidgetController.h b/src/FlightMap/Widgets/ValuesWidgetController.h
index d66b9bd..92398ae 100644
--- a/src/FlightMap/Widgets/ValuesWidgetController.h
+++ b/src/FlightMap/Widgets/ValuesWidgetController.h
@@ -7,42 +7,124 @@
*
****************************************************************************/
+#pragma once
-#ifndef ValuesWidgetController_H
-#define ValuesWidgetController_H
+#include "FactSystem.h"
+#include "QmlObjectListModel.h"
+#include "QGCApplication.h"
#include
+class ValuesWidgetController;
+
+class InstrumentValue : public QObject
+{
+ Q_OBJECT
+
+public:
+ enum FontSize {
+ DefaultFontSize=0,
+ SmallFontSize,
+ MediumFontSize,
+ LargeFontSize
+ };
+
+ InstrumentValue(Vehicle* activeVehicle, int fontSize, QmlObjectListModel* rowModel);
+
+ Q_PROPERTY(QString factGroupName MEMBER _factGroupName NOTIFY factGroupNameChanged)
+ Q_PROPERTY(Fact* fact READ fact NOTIFY factChanged)
+ Q_PROPERTY(QString label READ label WRITE setLabel NOTIFY labelChanged)
+ Q_PROPERTY(int fontSize READ fontSize WRITE setFontSize NOTIFY fontSizeChanged)
+ 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);
+
+ Fact* fact (void) { return _fact; }
+ int fontSize (void) const { return _fontSize; }
+ QString label (void) const { return _label; }
+ bool showUnits (void) const { return _showUnits; }
+ void setFontSize (int fontSize);
+ void setLabel (const QString& label);
+ void setShowUnits (bool showUnits);
+ void activeVehicleChanged (Vehicle* activeVehicle);
+ void saveToSettings (QSettings& settings) const;
+ void readFromSettings (const QSettings& settings);
+
+signals:
+ void factChanged (Fact* fact);
+ void factGroupNameChanged (QString factGroup);
+ void labelChanged (QString label);
+ void fontSizeChanged (int fontSize);
+ void showUnitsChanged (bool showUnits);
+
+private slots:
+
+private:
+ void _setFontSize(int fontSize);
+
+ Vehicle* _activeVehicle = nullptr;
+ QmlObjectListModel* _rowModel = nullptr;
+ Fact* _fact = nullptr;
+ QString _factGroupName;
+ QString _label;
+ bool _showUnits = true;
+ int _fontSize = DefaultFontSize;
+
+ static const char* _factGroupNameKey;
+ static const char* _factNameKey;
+ static const char* _labelKey;
+ static const char* _fontSizeKey;
+ static const char* _showUnitsKey;
+};
+
class ValuesWidgetController : public QObject
{
Q_OBJECT
public:
- ValuesWidgetController(void);
+ ValuesWidgetController(bool forDefaultSettingsCreation = false);
- Q_PROPERTY(QStringList largeValues READ largeValues WRITE setLargeValues NOTIFY largeValuesChanged)
- Q_PROPERTY(QStringList smallValues READ smallValues WRITE setSmallValues NOTIFY smallValuesChanged)
+ Q_PROPERTY(QmlObjectListModel* valuesModel READ valuesModel NOTIFY valuesModelChanged)
- Q_PROPERTY(QStringList altitudeProperties READ altitudeProperties CONSTANT)
+ 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);
- QStringList largeValues(void) const { return _largeValues; }
- QStringList smallValues(void) const { return _smallValues; }
- void setLargeValues(const QStringList& values);
- void setSmallValues(const QStringList& values);
- QStringList altitudeProperties(void) const { return _altitudeProperties; }
+ QmlObjectListModel* valuesModel(void) { return _valuesModel; }
+
+ /// Turn on/off saving changes to QSettings
+ void setPreventSaveSettings(bool preventSaveSettings);
signals:
- void largeValuesChanged(QStringList values);
- void smallValuesChanged(QStringList values);
+ void valuesModelChanged(QmlObjectListModel* valuesModel);
+
+private slots:
+ void _activeVehicleChanged(Vehicle* activeVehicle);
+ Vehicle* _currentActiveVehicle(void);
+ void _saveSettings (void);
private:
- QStringList _largeValues;
- QStringList _smallValues;
- QStringList _altitudeProperties;
+ bool _validRowIndex (int rowIndex);
+ InstrumentValue* _createNewInstrumentValueWorker (Vehicle* activeVehicle, int fontSize, QmlObjectListModel* rowModel);
+ void _loadSettings (void);
+
+ MultiVehicleManager* _multiVehicleMgr = nullptr;
+ QmlObjectListModel* _valuesModel = nullptr;
+ QVariantList _rgFontSizeByRow;
+ bool _preventSaveSettings = false;
static const char* _groupKey;
- static const char* _largeValuesKey;
- static const char* _smallValuesKey;
-};
+ static const char* _rowsKey;
+ static const char* _columnsKey;
+
+ static const char* _deprecatedGroupKey;
+ static const char* _deprecatedLargeValuesKey;
+ static const char* _deprecatedSmallValuesKey;
-#endif
+};
diff --git a/src/QGCApplication.cc b/src/QGCApplication.cc
index 4d06141..89d7522 100644
--- a/src/QGCApplication.cc
+++ b/src/QGCApplication.cc
@@ -100,6 +100,7 @@
#include "LogReplayLink.h"
#include "VehicleObjectAvoidance.h"
#include "TrajectoryPoints.h"
+#include "ValuesWidgetController.h"
#if defined(QGC_ENABLE_PAIRING)
#include "PairingManager.h"
@@ -523,6 +524,7 @@ 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 ("QGroundControl.FlightMap", 1, 0, "QGCMapCircle");
diff --git a/src/QmlControls/PageView.qml b/src/QmlControls/PageView.qml
index bece286..3cff0b3 100644
--- a/src/QmlControls/PageView.qml
+++ b/src/QmlControls/PageView.qml
@@ -17,6 +17,7 @@ Rectangle {
property real _margins: ScreenTools.defaultFontPixelWidth / 2
property real _pageWidth: _root.width
property var _instrumentPages: QGroundControl.corePlugin.instrumentPages
+ property bool _settingsUnlocked: false
QGCPalette { id:qgcPal; colorGroupEnabled: parent.enabled }
@@ -29,11 +30,13 @@ Rectangle {
centeredLabel: true
font.pointSize: ScreenTools.smallFontPointSize
+ onCurrentIndexChanged: _settingsUnlocked = false
+
QGCColoredImage {
anchors.leftMargin: _margins
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
- source: "/res/gear-black.svg"
+ source: pageWidgetLoader.item.showLockIcon ? (_settingsUnlocked ? "/res/LockOpen.svg" : "/res/LockClosed.svg") : "/res/gear-black.svg"
mipmap: true
height: parent.height * 0.7
width: height
@@ -44,7 +47,14 @@ Rectangle {
QGCMouseArea {
fillItem: parent
- onClicked: pageWidgetLoader.item.showSettings()
+ onClicked: {
+ if (pageWidgetLoader.item.showLockIcon) {
+ _settingsUnlocked = !_settingsUnlocked
+ pageWidgetLoader.item.showSettings(_settingsUnlocked)
+ } else {
+ pageWidgetLoader.item.showSettings()
+ }
+ }
}
}
}
diff --git a/src/QmlControls/QGCLabel.qml b/src/QmlControls/QGCLabel.qml
index ef0bded..26afb1b 100644
--- a/src/QmlControls/QGCLabel.qml
+++ b/src/QmlControls/QGCLabel.qml
@@ -1,9 +1,8 @@
-import QtQuick 2.3
-import QtQuick.Controls 1.2
-import QtQuick.Controls.Styles 1.4
+import QtQuick 2.12
+import QtQuick.Controls 2.12
-import QGroundControl.Palette 1.0
-import QGroundControl.ScreenTools 1.0
+import QGroundControl.Palette 1.0
+import QGroundControl.ScreenTools 1.0
Text {
font.pointSize: ScreenTools.defaultFontPointSize
diff --git a/src/api/QGCCorePlugin.cc b/src/api/QGCCorePlugin.cc
index 48be2c1..5c841cf 100644
--- a/src/api/QGCCorePlugin.cc
+++ b/src/api/QGCCorePlugin.cc
@@ -22,6 +22,7 @@
#endif
#include "QGCLoggingCategory.h"
#include "QGCCameraManager.h"
+#include "ValuesWidgetController.h"
#include
#include
@@ -406,10 +407,40 @@ QString QGCCorePlugin::showAdvancedUIMessage() const
"Are you sure you want to enable Advanced Mode?");
}
-void QGCCorePlugin::valuesWidgetDefaultSettings(QStringList& largeValues, QStringList& smallValues)
+QmlObjectListModel* QGCCorePlugin::valuesWidgetDefaultSettings(QObject* valuesModelParent)
{
- Q_UNUSED(smallValues);
- largeValues << "Vehicle.altitudeRelative" << "Vehicle.groundSpeed" << "Vehicle.flightTime";
+ 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", QString());
+ 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->setLabel(colValue->fact()->shortDescription());
+ colValue->setShowUnits(true);
+ colValue->setFontSize(InstrumentValue::DefaultFontSize);
+
+ columnModel = controller.appendRow();
+ colValue = columnModel->value(0);
+ colValue->setFact("Vehicle", "flightTime", QString());
+ colValue->setLabel(colValue->fact()->shortDescription());
+ colValue->setShowUnits(false);
+ colValue->setFontSize(InstrumentValue::DefaultFontSize);
+
+ controller.setPreventSaveSettings(false);
+
+ controller.valuesModel()->setParent(valuesModelParent);
+
+ return controller.valuesModel();
}
QQmlApplicationEngine* QGCCorePlugin::createRootWindow(QObject *parent)
diff --git a/src/api/QGCCorePlugin.h b/src/api/QGCCorePlugin.h
index 865bbf6..e8aa5eb 100644
--- a/src/api/QGCCorePlugin.h
+++ b/src/api/QGCCorePlugin.h
@@ -105,8 +105,9 @@ public:
/// Allows a plugin to override the specified color name from the palette
virtual void paletteOverride(QString colorName, QGCPalette::PaletteColorInfo_t& colorInfo);
- /// Allows the plugin to override the default settings for the Values Widget large and small values
- virtual void valuesWidgetDefaultSettings(QStringList& largeValues, QStringList& smallValues);
+ /// Return the default Intrument Value model for the Values Widget. The returned model will be
+ /// re-parented to valuesModelParent for ownership.
+ virtual QmlObjectListModel* valuesWidgetDefaultSettings(QObject* valuesModelParent);
/// Allows the plugin to override the creation of the root (native) window.
virtual QQmlApplicationEngine* createRootWindow(QObject* parent);