diff --git a/files/qml/FactTextInput.qml b/files/qml/FactTextInput.qml deleted file mode 100644 index 41212c0824aedb46d745a93782988778405744df..0000000000000000000000000000000000000000 --- a/files/qml/FactTextInput.qml +++ /dev/null @@ -1,13 +0,0 @@ -import QtQuick 2.2 -import QtQuick.Controls 1.2 -import QGroundControl.FactSystem 1.0 - -TextInput { - property Fact fact - text: fact.value - font.family: "Helvetica" - font.pointSize: 24 - color: "red" - focus: true - onAccepted: { fact.value = text; } -} diff --git a/qml/QGroundControl/FactControls/SetupButton.qml b/qml/QGroundControl/FactControls/SetupButton.qml new file mode 100644 index 0000000000000000000000000000000000000000..867537a3114715b217fb191e0b675624ebbfe82e --- /dev/null +++ b/qml/QGroundControl/FactControls/SetupButton.qml @@ -0,0 +1,163 @@ +import QtQuick 2.2 +import QtQuick.Controls 1.2 +import QtQuick.Controls.Styles 1.2 + +Button { + text: "Button" + property bool setupComplete: false + + property var summaryModel: ListModel { + ListElement { name: "Row 1"; state: "State 1" } + ListElement { name: "Row 2"; state: "State 2" } + ListElement { name: "Row 3"; state: "State 3" } + } + + style: ButtonStyle { + id: buttonStyle + background: Rectangle { + id: innerRect + readonly property real titleHeight: 30 + + //property alias summaryModel: summaryList.model + + border.color: "#888" + radius: 10 + + color: control.activeFocus ? "#47b" : "white" + opacity: control.hovered || control.activeFocus ? 1 : 0.75 + Behavior on opacity {NumberAnimation{ duration: 100 }} + + Text { + id: titleBar + + width: parent.width + height: parent.titleHeight + + verticalAlignment: TextEdit.AlignVCenter + horizontalAlignment: TextEdit.AlignHCenter + + text: control.text + font.pixelSize: 12 + + Rectangle { + id: setupIndicator + + property bool setupComplete: true + readonly property real indicatorRadius: 6 + + x: parent.width - (indicatorRadius * 2) - 5 + y: (parent.height - (indicatorRadius * 2)) / 2 + width: indicatorRadius * 2 + height: indicatorRadius * 2 + + radius: indicatorRadius + color: control.setupComplete ? "green" : "red" + } + } + + Rectangle { + width: parent.width + height: parent.height - parent.titleHeight + + y: parent.titleHeight + + border.color: "#888" + + gradient: Gradient { + GradientStop { position: 0; color: "#ffffff" } + GradientStop { position: 1; color: "#000000" } + } + + ListView { + id: summaryList + anchors.fill: parent + model: control.summaryModel + delegate: Row { + Text { text: modelData.name } + Text { text: modelData.state } + } + } + } + } + + label: Item {} + } +} + +/* +Rectangle { + readonly property real titleHeight: 30 + + property alias title: titleBar.text + property alias setupComplete: setupIndicator.setupComplete + //property alias summaryModel: summaryList.model + + border.color: "#888" + radius: 10 + + gradient: Gradient { + GradientStop { position: 0 ; color: "#cccccc" } + GradientStop { position: 1 ; color: "#aaa" } + } + + Text { + id: titleBar + + width: parent.width + height: parent.titleHeight + + verticalAlignment: TextEdit.AlignVCenter + horizontalAlignment: TextEdit.AlignHCenter + + text: qsTr("TITLE") + font.pixelSize: 12 + + Rectangle { + id: setupIndicator + + property bool setupComplete: true + readonly property real indicatorRadius: 6 + + x: parent.width - (indicatorRadius * 2) - 5 + y: (parent.height - (indicatorRadius * 2)) / 2 + width: indicatorRadius * 2 + height: indicatorRadius * 2 + + radius: indicatorRadius + color: setupComplete ? "green" : "red" + } + } + + Rectangle { + width: parent.width + height: parent.height - parent.titleHeight + + y: parent.titleHeight + + border.color: "#888" + + gradient: Gradient { + GradientStop { + position: 0 + color: "#ffffff" + } + + GradientStop { + position: 1 + color: "#000000" + } + } + + ListView { + id: summaryList + anchors.fill: parent + model: ListModel { + ListElement { name: "Row 1"; state: "State 1" } + ListElement { name: "Row 2"; state: "State 2" } + ListElement { name: "Row 3"; state: "State 3" } + } + delegate: Row { Text { text: modelData.name } Text { text: modelData.state } } + } + } +} +*/ \ No newline at end of file diff --git a/files/qml/qmldir b/qml/QGroundControl/FactControls/qmldir similarity index 50% rename from files/qml/qmldir rename to qml/QGroundControl/FactControls/qmldir index 3450add95ad4feb24daeaa5176d8a612d3b45d3a..5c68157e2fac6b076dd322fa917cecda1d8281f5 100644 --- a/files/qml/qmldir +++ b/qml/QGroundControl/FactControls/qmldir @@ -1,2 +1,2 @@ Module QGroundControl.FactControls -FactTextInput 1.0 FactTextInput.qml \ No newline at end of file +SetupButton 1.0 SetupButton.qml \ No newline at end of file diff --git a/src/AutoPilotPlugins/AutoPilotPlugin.h b/src/AutoPilotPlugins/AutoPilotPlugin.h index 34a388c8bf14c02c15f5ed01a3ab13614712cbb4..0fd2e7c196c030b3caf16822bfa324fc58369c53 100644 --- a/src/AutoPilotPlugins/AutoPilotPlugin.h +++ b/src/AutoPilotPlugins/AutoPilotPlugin.h @@ -48,18 +48,14 @@ class AutoPilotPlugin : public QObject Q_OBJECT public: - /// @brief Returns the list of VehicleComponent objects associated with the AutoPilot. - virtual QList getVehicleComponents(void) const = 0; + Q_PROPERTY(QVariantMap parameters READ parameters CONSTANT) + Q_PROPERTY(QVariantList components READ components CONSTANT) + Q_PROPERTY(QUrl setupBackgroundImage READ setupBackgroundImage CONSTANT) - /// Returns the parameter facts for the specified UAS. - /// - /// Key is parameter name. Get Fact object like this: _mapParameterName2Variant["RC_MAP_THROTTLE"].value(). - /// You should not request parameter facts until the plugin reports that it is ready. - virtual const QVariantMap& parameterFacts(void) const = 0; - - /// Adds the FactSystem properties to the Qml context. You should not call - /// this method until the plugin reports that it is ready. - virtual void addFactsToQmlContext(QQmlContext* context) const = 0; + // Property accessors + virtual const QVariantList& components(void) = 0; + virtual const QVariantMap& parameters(void) = 0; + virtual QUrl setupBackgroundImage(void) = 0; /// Returns true if the plugin is ready for use virtual bool pluginIsReady(void) const = 0; @@ -72,8 +68,9 @@ signals: void pluginReady(void); protected: - // All access to AutoPilotPugin objects is through getInstanceForAutoPilotPlugin + /// All access to AutoPilotPugin objects is through getInstanceForAutoPilotPlugin AutoPilotPlugin(QObject* parent = NULL) : QObject(parent) { } + }; #endif diff --git a/src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.cc b/src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.cc index f2d876fa76d8c74ad4ecb46aa8ae5aff773cc804..d6fd7b3d228b4a1af91495da14ea53c966e49558 100644 --- a/src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.cc +++ b/src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.cc @@ -32,12 +32,6 @@ GenericAutoPilotPlugin::GenericAutoPilotPlugin(UASInterface* uas, QObject* paren Q_UNUSED(uas); } -QList GenericAutoPilotPlugin::getVehicleComponents(void) const -{ - // Generic autopilot has no configurable components - return QList(); -} - QList GenericAutoPilotPlugin::getModes(void) { AutoPilotPluginManager::FullMode_t fullMode; @@ -83,13 +77,20 @@ QString GenericAutoPilotPlugin::getShortModeText(uint8_t baseMode, uint32_t cust return mode; } -void GenericAutoPilotPlugin::addFactsToQmlContext(QQmlContext* context) const +void GenericAutoPilotPlugin::clearStaticData(void) { - Q_UNUSED(context); + // No Static data yet +} + +const QVariantList& GenericAutoPilotPlugin::components(void) +{ + static QVariantList staticList; + Q_ASSERT_X(false, "Not yet implemented", ""); + return staticList; } -const QVariantMap& GenericAutoPilotPlugin::parameterFacts(void) const +const QVariantMap& GenericAutoPilotPlugin::parameters(void) { static QVariantMap staticMap; @@ -97,7 +98,10 @@ const QVariantMap& GenericAutoPilotPlugin::parameterFacts(void) const return staticMap; } -void GenericAutoPilotPlugin::clearStaticData(void) +QUrl GenericAutoPilotPlugin::setupBackgroundImage(void) { - // No Static data yet + static QUrl url; + + Q_ASSERT_X(false, "Not yet implemented", ""); + return url; } diff --git a/src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.h b/src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.h index 2eee6c7ed529ea5b7d086d4b2bcf64f144107609..9e9b4f86bcadb860417b1c045b20855d691dffe8 100644 --- a/src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.h +++ b/src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.h @@ -40,14 +40,16 @@ public: GenericAutoPilotPlugin(UASInterface* uas, QObject* parent = NULL); // Overrides from AutoPilotPlugin - virtual QList getVehicleComponents(void) const ; - virtual void addFactsToQmlContext(QQmlContext* context) const; - virtual const QVariantMap& parameterFacts(void) const; virtual bool pluginIsReady(void) const { return true; } + virtual QUrl setupBackgroundImage(void); + virtual const QVariantList& components(void); + virtual const QVariantMap& parameters(void); static QList getModes(void); static QString getShortModeText(uint8_t baseMode, uint32_t customMode); static void clearStaticData(void); + +protected: }; #endif diff --git a/src/AutoPilotPlugins/PX4/AirframeComponent.cc b/src/AutoPilotPlugins/PX4/AirframeComponent.cc index 1c26f2940998c679465198db1d82d64630277a84..c63f5334ac26479e3edfe035749f0fc54060024b 100644 --- a/src/AutoPilotPlugins/PX4/AirframeComponent.cc +++ b/src/AutoPilotPlugins/PX4/AirframeComponent.cc @@ -26,6 +26,7 @@ #include "AirframeComponent.h" #include "QGCPX4AirframeConfig.h" +#include "VehicleComponentSummaryItem.h" /// @brief Parameters which signal a change in setupComplete state static const char* triggerParams[] = { "SYS_AUTOSTART", NULL }; @@ -161,56 +162,65 @@ QWidget* AirframeComponent::setupWidget(void) const return new QGCPX4AirframeConfig; } -QList AirframeComponent::summaryItems(void) const +const QVariantList& AirframeComponent::summaryItems(void) { - QVariant value; - QStringList row; - QList items; + // Fill the items on first reference + // FIXME: These items are not live - row << "System ID:"; - if (_paramMgr->getParameterValue(_paramMgr->getDefaultComponentId(), "MAV_SYS_ID", value)) { - if (value.toInt() == 0) { - row << "Setup required"; + if (!_summaryItems.count()) { + QString name; + QString state; + QVariant value; + + name = "System ID:"; + if (_paramMgr->getParameterValue(_paramMgr->getDefaultComponentId(), "MAV_SYS_ID", value)) { + if (value.toInt() == 0) { + state = "Setup required"; + } else { + state = value.toString(); + } } else { - row << value.toString(); + // Why is the parameter missing? + Q_ASSERT(false); } - } else { - // Why is the parameter missing? - Q_ASSERT(false); - } - items << row; - - row.clear(); - row << "Airframe:"; - if (_paramMgr->getParameterValue(_paramMgr->getDefaultComponentId(), "SYS_AUTOSTART", value)) { - if (value.toInt() == 0) { - row << "Setup required"; + + VehicleComponentSummaryItem* item = new VehicleComponentSummaryItem(name, state, this); + _summaryItems.append(QVariant::fromValue(item)); + + name = "Airframe:"; + if (_paramMgr->getParameterValue(_paramMgr->getDefaultComponentId(), "SYS_AUTOSTART", value)) { + if (value.toInt() == 0) { + state = "Setup required"; + } else { + state = value.toString(); + } } else { - row << value.toString(); + // Why is the parameter missing? + Q_ASSERT(false); } - } else { - // Why is the parameter missing? - Q_ASSERT(false); - } - items << row; - - row.clear(); - row << "Type:"; - if (_paramMgr->getParameterValue(_paramMgr->getDefaultComponentId(), "MAV_TYPE", value)) { - int index = value.toInt(); + + item = new VehicleComponentSummaryItem(name, state, this); + _summaryItems.append(QVariant::fromValue(item)); - if (index < 0 || index >= (int)cMavTypes) { - row << "Unknown"; + name = "Type:"; + if (_paramMgr->getParameterValue(_paramMgr->getDefaultComponentId(), "MAV_TYPE", value)) { + int index = value.toInt(); + + if (index < 0 || index >= (int)cMavTypes) { + state = "Unknown"; + } else { + state = mavTypeInfo[index].description; + } } else { - row << mavTypeInfo[index].description; + // Why is the parameter missing? + Q_ASSERT(false); + state = "Unknown"; } - } else { - // Why is the parameter missing? - Q_ASSERT(false); - row << "Unknown"; + + item = new VehicleComponentSummaryItem(name, state, this); + _summaryItems.append(QVariant::fromValue(item)); } - items << row; - - return items; + + return _summaryItems; } diff --git a/src/AutoPilotPlugins/PX4/AirframeComponent.h b/src/AutoPilotPlugins/PX4/AirframeComponent.h index a373a0675b63e7bdc41db505020272bfee12f8be..5891a18d8816dff7f657a273d61865b056317ed4 100644 --- a/src/AutoPilotPlugins/PX4/AirframeComponent.h +++ b/src/AutoPilotPlugins/PX4/AirframeComponent.h @@ -49,10 +49,11 @@ public: virtual QString setupStateDescription(void) const; virtual QWidget* setupWidget(void) const; virtual QStringList paramFilterList(void) const; - virtual QList summaryItems(void) const; + virtual const QVariantList& summaryItems(void); private: - const QString _name; + const QString _name; + QVariantList _summaryItems; }; #endif diff --git a/src/AutoPilotPlugins/PX4/FlightModeConfig.ui b/src/AutoPilotPlugins/PX4/FlightModeConfig.ui index c8ad74899e343ec1111b4a9f57285eea5f6543ff..fce5fc124f90853fbff5986a68d52151b994881a 100644 --- a/src/AutoPilotPlugins/PX4/FlightModeConfig.ui +++ b/src/AutoPilotPlugins/PX4/FlightModeConfig.ui @@ -6,27 +6,28 @@ 0 0 - 831 - 1286 + 642 + 645 - + 0 0 + + + 642 + 645 + + Form - - - 22 - - This implementation is a work in progress. Visuals are meant to be functional only. Active display of switch positions is not yet implemented. If this entire screen is disabled, you must do a Radio Calibration before settings Flight Modes. @@ -205,19 +206,6 @@ - - - - Qt::Vertical - - - - 20 - 40 - - - - diff --git a/src/AutoPilotPlugins/PX4/FlightModesComponent.cc b/src/AutoPilotPlugins/PX4/FlightModesComponent.cc index d7a857a47f9ba5b39635d06371d44fefbc42d8f9..d797d81955eaa9f096648e13d24b077026e87ba2 100644 --- a/src/AutoPilotPlugins/PX4/FlightModesComponent.cc +++ b/src/AutoPilotPlugins/PX4/FlightModesComponent.cc @@ -26,6 +26,7 @@ #include "FlightModesComponent.h" #include "FlightModeConfig.h" +#include "VehicleComponentSummaryItem.h" /// @brief Parameters which signal a change in setupComplete state static const char* triggerParams[] = { "RC_MAP_MODE_SW", NULL }; @@ -116,41 +117,44 @@ QWidget* FlightModesComponent::setupWidget(void) const return new FlightModeConfig(); } -QList FlightModesComponent::summaryItems(void) const +const QVariantList& FlightModesComponent::summaryItems(void) { - QList items; - - // Create summary items for each mode switch - - for (size_t i=0; igetParameterValue(_paramMgr->getDefaultComponentId(), switchList[i].param, value)) { - int chan = value.toInt(); + for (size_t i=0; igetParameterValue(_paramMgr->getDefaultComponentId(), switchList[i].param, value)) { + int chan = value.toInt(); + + if (chan == 0) { + // Switch is not mapped + if (i == 0) { + // Mode switch is required + Q_ASSERT(strcmp(switchList[0].param, "RC_MAP_MODE_SW") == 0); + state = "Setup required"; + } else { + state = "None"; + } } else { - row << "None"; + state = tr("Chan %1").arg(chan); } } else { - row << tr("Chan %1").arg(chan); + // Why is the parameter missing? + Q_ASSERT(false); + state = "Unknown"; } - } else { - // Why is the parameter missing? - Q_ASSERT(false); - row << "Unknown"; + + VehicleComponentSummaryItem* item = new VehicleComponentSummaryItem(name, state, this); + _summaryItems.append(QVariant::fromValue(item)); } - - items << row; } - return items; + return _summaryItems; } diff --git a/src/AutoPilotPlugins/PX4/FlightModesComponent.h b/src/AutoPilotPlugins/PX4/FlightModesComponent.h index 7f20d97ba50abc287f87ad8544776e37014abda6..079d2907ca75ae00e8f0ef780de35d0bb79d713b 100644 --- a/src/AutoPilotPlugins/PX4/FlightModesComponent.h +++ b/src/AutoPilotPlugins/PX4/FlightModesComponent.h @@ -49,10 +49,11 @@ public: virtual QString setupStateDescription(void) const; virtual QWidget* setupWidget(void) const; virtual QStringList paramFilterList(void) const; - virtual QList summaryItems(void) const; + virtual const QVariantList& summaryItems(void); private: - const QString _name; + const QString _name; + QVariantList _summaryItems; }; #endif diff --git a/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.cc b/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.cc index a2fce1fa65b3db7edbe6330eabd8815986c48385..446a8c7ab6f8c8168ad7f9469c1385e5ed4fe69a 100644 --- a/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.cc +++ b/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.cc @@ -86,33 +86,6 @@ PX4AutoPilotPlugin::~PX4AutoPilotPlugin() PX4ParameterFacts::deleteParameterFactMetaData(); } -QList PX4AutoPilotPlugin::getVehicleComponents(void) const -{ - Q_ASSERT(_uas); - - QList components; - - VehicleComponent* component; - - component = new AirframeComponent(_uas); - Q_CHECK_PTR(component); - components.append(component); - - component = new RadioComponent(_uas); - Q_CHECK_PTR(component); - components.append(component); - - component = new FlightModesComponent(_uas); - Q_CHECK_PTR(component); - components.append(component); - - component = new SensorsComponent(_uas); - Q_CHECK_PTR(component); - components.append(component); - - return components; -} - QList PX4AutoPilotPlugin::getModes(void) { union px4_custom_mode px4_cm; @@ -206,15 +179,6 @@ QString PX4AutoPilotPlugin::getShortModeText(uint8_t baseMode, uint32_t customMo return mode; } -void PX4AutoPilotPlugin::addFactsToQmlContext(QQmlContext* context) const -{ - Q_ASSERT(context); - - Q_ASSERT(_parameterFacts->factsAreReady()); - - context->setContextProperty("parameters", _parameterFacts->factMap()); -} - void PX4AutoPilotPlugin::clearStaticData(void) { PX4ParameterFacts::clearStaticData(); @@ -224,3 +188,40 @@ bool PX4AutoPilotPlugin::pluginIsReady(void) const { return _parameterFacts->factsAreReady(); } + +const QVariantList& PX4AutoPilotPlugin::components(void) +{ + if (_components.count() == 0) { + VehicleComponent* component; + + Q_ASSERT(_uas); + + component = new AirframeComponent(_uas); + Q_CHECK_PTR(component); + _components.append(QVariant::fromValue(component)); + + component = new RadioComponent(_uas); + Q_CHECK_PTR(component); + _components.append(QVariant::fromValue(component)); + + component = new FlightModesComponent(_uas); + Q_CHECK_PTR(component); + _components.append(QVariant::fromValue(component)); + + component = new SensorsComponent(_uas); + Q_CHECK_PTR(component); + _components.append(QVariant::fromValue(component)); + } + + return _components; +} + +const QVariantMap& PX4AutoPilotPlugin::parameters(void) +{ + return _parameterFacts->factMap(); +} + +QUrl PX4AutoPilotPlugin::setupBackgroundImage(void) +{ + return QUrl::fromUserInput("qrc:/qml/px4fmu_2.x.png"); +} diff --git a/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.h b/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.h index a823ed41c6c6e27d88a305843bf2b386321fc4b3..6607983a032a27bd95856ad103fe69c054cad639 100644 --- a/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.h +++ b/src/AutoPilotPlugins/PX4/PX4AutoPilotPlugin.h @@ -29,6 +29,8 @@ #include "UASInterface.h" #include "PX4ParameterFacts.h" +#include + /// @file /// @brief This is the PX4 specific implementation of the AutoPilot class. /// @author Don Gagne @@ -42,10 +44,10 @@ public: ~PX4AutoPilotPlugin(); // Overrides from AutoPilotPlugin - virtual QList getVehicleComponents(void) const ; - virtual void addFactsToQmlContext(QQmlContext* context) const; - virtual const QVariantMap& parameterFacts(void) const { return _parameterFacts->factMap(); } virtual bool pluginIsReady(void) const; + virtual const QVariantList& components(void); + virtual const QVariantMap& parameters(void); + virtual QUrl setupBackgroundImage(void); static QList getModes(void); static QString getShortModeText(uint8_t baseMode, uint32_t customMode); @@ -55,6 +57,7 @@ private: UASInterface* _uas; PX4ParameterFacts* _parameterFacts; bool _pluginReady; + QVariantList _components; }; #endif diff --git a/src/AutoPilotPlugins/PX4/RadioComponent.cc b/src/AutoPilotPlugins/PX4/RadioComponent.cc index 2521351dbeff0040c4b0b5a5467cc56f6d990a0e..a071a6c57720995376138c7c80bad604e37885db 100644 --- a/src/AutoPilotPlugins/PX4/RadioComponent.cc +++ b/src/AutoPilotPlugins/PX4/RadioComponent.cc @@ -26,6 +26,7 @@ #include "RadioComponent.h" #include "PX4RCCalibration.h" +#include "VehicleComponentSummaryItem.h" /// @brief Parameters which signal a change in setupComplete state static const char* triggerParams[] = { "RC_MAP_MODE_SW", NULL }; @@ -100,48 +101,54 @@ QWidget* RadioComponent::setupWidget(void) const return new PX4RCCalibration; } -QList RadioComponent::summaryItems(void) const +const QVariantList& RadioComponent::summaryItems(void) { - QList items; - - QStringList row; - - // FIXME: Need to pull receiver type from RSSI value - row << "Receiver type:" << "n/a"; - items << row; - - static const char* stickParams[] = { "RC_MAP_ROLL", "RC_MAP_PITCH", "RC_MAP_YAW", "RC_MAP_THROTTLE" }; - - QString summary("Chan "); - - bool allSticksMapped = true; - for (size_t i=0; igetParameterValue(_paramMgr->getDefaultComponentId(), stickParams[i], value)) { - if (value.toInt() == 0) { - allSticksMapped = false; - break; - } else { - if (i != 0) { - summary += ","; + // FIXME: Need to pull receiver type from RSSI value + name = "Receiver type:"; + state = "n/a"; + + VehicleComponentSummaryItem* item = new VehicleComponentSummaryItem(name, state, this); + _summaryItems.append(QVariant::fromValue(item)); + + static const char* stickParams[] = { "RC_MAP_ROLL", "RC_MAP_PITCH", "RC_MAP_YAW", "RC_MAP_THROTTLE" }; + + QString summary("Chan "); + + bool allSticksMapped = true; + for (size_t i=0; igetParameterValue(_paramMgr->getDefaultComponentId(), stickParams[i], value)) { + if (value.toInt() == 0) { + allSticksMapped = false; + break; + } else { + if (i != 0) { + summary += ","; + } + summary += value.toString(); } - summary += value.toString(); + } else { + // Why is the parameter missing? + Q_ASSERT(false); + summary += "?"; } - } else { - // Why is the parameter missing? - Q_ASSERT(false); - summary += "?"; } - } - - if (!allSticksMapped) { - summary = "Not mapped"; - } + + if (!allSticksMapped) { + summary = "Not mapped"; + } - row.clear(); - row << "Ail, Ele, Rud, Throt:" << summary; - items << row; + name = "Ail, Ele, Rud, Throt:"; + state = summary; + + item = new VehicleComponentSummaryItem(name, state, this); + _summaryItems.append(QVariant::fromValue(item)); + } - return items; + return _summaryItems; } diff --git a/src/AutoPilotPlugins/PX4/RadioComponent.h b/src/AutoPilotPlugins/PX4/RadioComponent.h index 544969e5231aaa5c7abe137a44fe0d094e193327..8c6c948df6e3a56ceb69482dd99b51125fe1ad11 100644 --- a/src/AutoPilotPlugins/PX4/RadioComponent.h +++ b/src/AutoPilotPlugins/PX4/RadioComponent.h @@ -50,10 +50,11 @@ public: virtual QString setupStateDescription(void) const; virtual QWidget* setupWidget(void) const; virtual QStringList paramFilterList(void) const; - virtual QList summaryItems(void) const; + virtual const QVariantList& summaryItems(void); private: - const QString _name; + const QString _name; + QVariantList _summaryItems; }; #endif diff --git a/src/AutoPilotPlugins/PX4/SensorsComponent.cc b/src/AutoPilotPlugins/PX4/SensorsComponent.cc index 43911278bef9c99bce86f9f6d3550ad1159f4e66..2e2cd57fd2f4b3b8f3b2698edd74f268df6b9c3b 100644 --- a/src/AutoPilotPlugins/PX4/SensorsComponent.cc +++ b/src/AutoPilotPlugins/PX4/SensorsComponent.cc @@ -26,6 +26,7 @@ #include "SensorsComponent.h" #include "QGCPX4SensorCalibration.h" +#include "VehicleComponentSummaryItem.h" // These two list must be kept in sync @@ -116,106 +117,108 @@ QWidget* SensorsComponent::setupWidget(void) const return new QGCPX4SensorCalibration; } -QList SensorsComponent::summaryItems(void) const +const QVariantList& SensorsComponent::summaryItems(void) { - QList items; - - // Summary item for each Sensor - - int i = 0; - while (triggerParams[i] != NULL) { - QVariant value; - QStringList row; + if (!_summaryItems.count()) { + QString name; + QString state; - row << tr("%1:").arg(triggerSensors[i]); + // Summary item for each Sensor - if (_paramMgr->getParameterValue(_paramMgr->getDefaultComponentId(), triggerParams[i], value)) { - if (value.toFloat() == 0.0f) { - row << "Setup required"; + int i = 0; + while (triggerParams[i] != NULL) { + QVariant value; + + name = tr("%1:").arg(triggerSensors[i]); + + if (_paramMgr->getParameterValue(_paramMgr->getDefaultComponentId(), triggerParams[i], value)) { + if (value.toFloat() == 0.0f) { + state = "Setup required"; + } else { + state = "Ready"; + } } else { - row << "Ready"; + // Why is the parameter missing? + Q_ASSERT(false); } - } else { - // Why is the parameter missing? - Q_ASSERT(false); + + VehicleComponentSummaryItem* item = new VehicleComponentSummaryItem(name, state, this); + _summaryItems.append(QVariant::fromValue(item)); + + i++; } - items << row; - i++; - } - - // Summary item for each orientation param - - static const char* orientationSensors[] = { "Autopilot orientation:", "Compass orientation:" }; - static const char* orientationParams[] = { "SENS_BOARD_ROT", "SENS_EXT_MAG_ROT" }; - static const size_t cOrientationSensors = sizeof(orientationSensors)/sizeof(orientationSensors[0]); - - static const char* orientationValues[] = { - "Line of flight", - "Yaw:45", - "Yaw:90", - "Yaw:135", - "Yaw:180", - "Yaw:225", - "Yaw:270", - "Yaw:315", - "Roll:180", - "Roll:180 Yaw:45", - "Roll:180 Yaw:90", - "Roll:180 Yaw:135", - "Pitch:180", - "Roll:180 Yaw:225", - "Roll:180 Yaw:270", - "Roll:180 Yaw:315", - "Roll:90", - "Roll:90 Yaw:45", - "Roll:90 Yaw:90", - "Roll:90 Yaw:135", - "Roll:270", - "Roll:270 Yaw:45", - "Roll:270 Yaw:90", - "Roll:270 Yaw:135", - "Pitch:90", - "Pitch:270", - "Pitch:180", - "Pitch:180 Yaw:90", - "Pitch:180 Yaw:270", - "Roll:90 Pitch:90", - "Roll:180 Pitch:90", - "Roll:270 Pitch:90", - "Roll:90 Pitch:180", - "Roll:270 Pitch:180", - "Roll:90 Pitch:270", - "Roll:180 Pitch:270", - "Roll:270 Pitch:270", - "Roll:90 Pitch:180 Yaw:90", - "Roll:90 Yaw:270" - }; - static const size_t cOrientationValues = sizeof(orientationValues)/sizeof(orientationValues[0]); - - for (size_t i=0; igetParameterValue(_paramMgr->getDefaultComponentId(), orientationParams[i], value)) { - int index = value.toInt(); - if (index < 0 || index >= (int)cOrientationValues) { - row << "Setup required"; + for (size_t i=0; igetParameterValue(_paramMgr->getDefaultComponentId(), orientationParams[i], value)) { + int index = value.toInt(); + if (index < 0 || index >= (int)cOrientationValues) { + state = "Setup required"; + } else { + state = orientationValues[index]; + } } else { - row << orientationValues[index]; + // Why is the parameter missing? + Q_ASSERT(false); + state = "Unknown"; } - } else { - // Why is the parameter missing? - Q_ASSERT(false); - row << "Unknown"; + + VehicleComponentSummaryItem* item = new VehicleComponentSummaryItem(name, state, this); + _summaryItems.append(QVariant::fromValue(item)); } - - items << row; } - return items; + return _summaryItems; } diff --git a/src/AutoPilotPlugins/PX4/SensorsComponent.h b/src/AutoPilotPlugins/PX4/SensorsComponent.h index d3d14c19a9db289eb9ee2a91d0e07ae34661ba38..52a68155a9865890407cfa489f31207ca0de1a89 100644 --- a/src/AutoPilotPlugins/PX4/SensorsComponent.h +++ b/src/AutoPilotPlugins/PX4/SensorsComponent.h @@ -49,10 +49,11 @@ public: virtual QString setupStateDescription(void) const; virtual QWidget* setupWidget(void) const; virtual QStringList paramFilterList(void) const; - virtual QList summaryItems(void) const; + virtual const QVariantList& summaryItems(void); private: - const QString _name; + const QString _name; + QVariantList _summaryItems; }; #endif diff --git a/src/FactSystem/FactSystem.cc b/src/FactSystem/FactSystem.cc index 401efd61d5936609496ae9323ff6cb553414fab2..8d8b8103c4ef207f7b207f07c6a29d24ffb42484 100644 --- a/src/FactSystem/FactSystem.cc +++ b/src/FactSystem/FactSystem.cc @@ -27,6 +27,7 @@ #include "FactSystem.h" #include "UASManager.h" #include "QGCApplication.h" +#include "VehicleComponent.h" #include @@ -39,6 +40,10 @@ FactSystem::FactSystem(QObject* parent) : { qmlRegisterType(_factSystemQmlUri, 1, 0, "Fact"); qmlRegisterType(_factSystemQmlUri, 1, 0, "FactValidator"); + + // FIXME: Where should this go? Also creation string + qmlRegisterUncreatableType(_factSystemQmlUri, 1, 0, "VehicleComponent", "Can only reference VehicleComponent"); + qmlRegisterUncreatableType(_factSystemQmlUri, 1, 0, "VehicleComponentSummaryItem", "Can only reference VehicleComponentSummaryItem"); } FactSystem::~FactSystem() diff --git a/src/FactSystem/FactSystemTest.cc b/src/FactSystem/FactSystemTest.cc index a4241743d4ef9b2c0c4fd0bbc3498671cc846e34..bc0f6060dd4801aebde3643cb686e154b06bfc17 100644 --- a/src/FactSystem/FactSystemTest.cc +++ b/src/FactSystem/FactSystemTest.cc @@ -90,13 +90,7 @@ void FactSystemTest::_parameter_test(void) { // Get the parameter facts from the AutoPilot - AutoPilotPluginManager* pluginMgr = AutoPilotPluginManager::instance(); - Q_ASSERT(pluginMgr); - - AutoPilotPlugin* plugin = pluginMgr->getInstanceForAutoPilotPlugin(_uas); - Q_ASSERT(plugin); - - const QVariantMap& parameterFacts = plugin->parameterFacts(); + const QVariantMap& parameterFacts = _plugin->parameters(); // Compare the value in the Parameter Manager with the value from the FactSystem @@ -116,6 +110,8 @@ void FactSystemTest::_qml_test(void) { QGCQuickWidget* widget = new QGCQuickWidget; + widget->setAutoPilot(_plugin); + widget->setSource(QUrl::fromUserInput("qrc:unittest/FactSystemTest.qml")); QQuickItem* rootObject = widget->rootObject(); @@ -134,13 +130,7 @@ void FactSystemTest::_paramMgrSignal_test(void) { // Get the parameter Fact from the AutoPilot - AutoPilotPluginManager* pluginMgr = AutoPilotPluginManager::instance(); - Q_ASSERT(pluginMgr); - - AutoPilotPlugin* plugin = pluginMgr->getInstanceForAutoPilotPlugin(_uas); - Q_ASSERT(plugin); - - const QVariantMap& parameterFacts = plugin->parameterFacts(); + const QVariantMap& parameterFacts = _plugin->parameters(); Fact* fact = parameterFacts["RC_MAP_THROTTLE"].value(); QVERIFY(fact != NULL); @@ -170,6 +160,8 @@ void FactSystemTest::_qmlUpdate_test(void) { QGCQuickWidget* widget = new QGCQuickWidget; + widget->setAutoPilot(_plugin); + widget->setSource(QUrl::fromUserInput("qrc:unittest/FactSystemTest.qml")); // Change the value using param manager diff --git a/src/FactSystem/FactSystemTest.qml b/src/FactSystem/FactSystemTest.qml index 2b90442514fcdf53ea751e2cfd3fbf2f9794f13f..d18a8578ad1c8997663f3eddbae1a10cb208a91e 100644 --- a/src/FactSystem/FactSystemTest.qml +++ b/src/FactSystem/FactSystemTest.qml @@ -1,16 +1,15 @@ import QtQuick 2.2 import QtQuick.Controls 1.2 import QGroundControl.FactSystem 1.0 -import QGroundControlFactControls 1.0 Item { TextInput { objectName: "testControl" - text: parameters["RC_MAP_THROTTLE"].value + text: autopilot.parameters["RC_MAP_THROTTLE"].value font.family: "Helvetica" font.pointSize: 24 color: "red" focus: true - onAccepted: { parameters["RC_MAP_THROTTLE"].value = text; } + onAccepted: { autopilot.parameters["RC_MAP_THROTTLE"].value = text; } } } \ No newline at end of file diff --git a/src/QGCQuickWidget.cc b/src/QGCQuickWidget.cc index 40057075a183dad7a89b413f4f8ef42810769a8f..f15b78530805880e08186b07bb33a9a1e517a9e4 100644 --- a/src/QGCQuickWidget.cc +++ b/src/QGCQuickWidget.cc @@ -22,7 +22,6 @@ ======================================================================*/ #include "QGCQuickWidget.h" -#include "UASManager.h" #include "AutoPilotPluginManager.h" #include @@ -37,13 +36,10 @@ QGCQuickWidget::QGCQuickWidget(QWidget* parent) : QQuickWidget(parent) { - UASManagerInterface* uasMgr = UASManager::instance(); - Q_ASSERT(uasMgr); - - UASInterface* uas = uasMgr->getActiveUAS(); - Q_ASSERT(uas); - rootContext()->engine()->addImportPath("qrc:/qml"); - - AutoPilotPluginManager::instance()->getInstanceForAutoPilotPlugin(uas)->addFactsToQmlContext(rootContext()); +} + +void QGCQuickWidget::setAutoPilot(AutoPilotPlugin* autoPilot) +{ + rootContext()->setContextProperty("autopilot", autoPilot); } diff --git a/src/QGCQuickWidget.h b/src/QGCQuickWidget.h index a239cff3accecfa38651b76b7e2c1d6e88b00fbb..22a166ba5aa99e2d060ddf4d114c416efc815d2b 100644 --- a/src/QGCQuickWidget.h +++ b/src/QGCQuickWidget.h @@ -26,7 +26,7 @@ #include -#include "UASInterface.h" +#include "AutoPilotPlugin.h" /// @file /// @brief Subclass of QQuickWidget which injects Facts and the Pallete object into @@ -39,7 +39,9 @@ class QGCQuickWidget : public QQuickWidget { public: QGCQuickWidget(QWidget* parent = NULL); + + /// Sets the UAS into the widget which in turn will load facts into the context + void setAutoPilot(AutoPilotPlugin* autoPilot); }; - #endif diff --git a/src/VehicleSetup/VehicleComponent.cc b/src/VehicleSetup/VehicleComponent.cc index fb10a03e510e6de105e3579ae42f8a4a6b2fc410..0bb5eb923d06b3408bfb4d3779ed93a2869cf834 100644 --- a/src/VehicleSetup/VehicleComponent.cc +++ b/src/VehicleSetup/VehicleComponent.cc @@ -38,3 +38,20 @@ VehicleComponent::~VehicleComponent() { } + +void VehicleComponent::addSummaryQmlComponent(QQmlContext* context, QQuickItem* parent) +{ + Q_ASSERT(context); + + // FIXME: We own this object now, need to delete somewhere + QQmlComponent component(context->engine(), QUrl::fromUserInput("qrc:/qml/VehicleComponentSummaryButton.qml")); + if (component.status() == QQmlComponent::Error) { + qDebug() << component.errors(); + Q_ASSERT(false); + } + + QQuickItem* item = qobject_cast(component.create(context)); + Q_ASSERT(item); + item->setParentItem(parent); + item->setProperty("vehicleComponent", QVariant::fromValue(this)); +} diff --git a/src/VehicleSetup/VehicleComponent.h b/src/VehicleSetup/VehicleComponent.h index cc6baeb62ce5b3e0849f8e0c752156aac7021b2f..48c5c69248e7a48538ff4fe75d4f972b10f08d42 100644 --- a/src/VehicleSetup/VehicleComponent.h +++ b/src/VehicleSetup/VehicleComponent.h @@ -25,6 +25,8 @@ #define VEHICLECOMPONENT_H #include +#include +#include #include "UASInterface.h" @@ -37,6 +39,7 @@ class VehicleComponent : public QObject { Q_OBJECT + Q_PROPERTY(QString name READ name CONSTANT) Q_PROPERTY(QString description READ description CONSTANT) Q_PROPERTY(bool requiresSetup READ requiresSetup CONSTANT) @@ -44,6 +47,7 @@ class VehicleComponent : public QObject Q_PROPERTY(QString setupStateDescription READ setupStateDescription STORED false) Q_PROPERTY(QString icon READ icon CONSTANT) Q_PROPERTY(QWidget* setupWidget READ setupWidget STORED false) + Q_PROPERTY(QVariantList summaryItems READ summaryItems CONSTANT); public: VehicleComponent(UASInterface* uas, QObject* parent = NULL); @@ -57,7 +61,9 @@ public: virtual QString setupStateDescription(void) const = 0; virtual QWidget* setupWidget(void) const = 0; virtual QStringList paramFilterList(void) const = 0; - virtual QList summaryItems(void) const = 0; + virtual const QVariantList& summaryItems(void) = 0; + + virtual void addSummaryQmlComponent(QQmlContext* context, QQuickItem* parent); signals: void setupCompleteChanged(void); diff --git a/src/VehicleSetup/VehicleComponentSummaryButton.qml b/src/VehicleSetup/VehicleComponentSummaryButton.qml new file mode 100644 index 0000000000000000000000000000000000000000..5da21da58248f507dfbf0606f2af24fc92a6bf3b --- /dev/null +++ b/src/VehicleSetup/VehicleComponentSummaryButton.qml @@ -0,0 +1,9 @@ +import QtQuick 2.2 +import QtQuick.Controls 1.2 +import QGroundControlFactControls 1.0 + +SetupButton { + width: 300 + height: 200 + title: vehicleComponent.name +} diff --git a/src/VehicleSetup/VehicleComponentSummaryItem.cc b/src/VehicleSetup/VehicleComponentSummaryItem.cc new file mode 100644 index 0000000000000000000000000000000000000000..753d6de207e522deb458e390036971f4bffe8967 --- /dev/null +++ b/src/VehicleSetup/VehicleComponentSummaryItem.cc @@ -0,0 +1,35 @@ +/*===================================================================== + + QGroundControl Open Source Ground Control Station + + (c) 2009 - 2014 QGROUNDCONTROL PROJECT + + This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QGROUNDCONTROL. If not, see . + + ======================================================================*/ + +/// @file +/// @author Don Gagne + +#include "VehicleComponentSummaryItem.h" + +VehicleComponentSummaryItem::VehicleComponentSummaryItem(const QString& name, const QString& state, QObject* parent) : + QObject(parent), + _name(name), + _state(state) +{ + +} diff --git a/src/VehicleSetup/VehicleComponentSummaryItem.h b/src/VehicleSetup/VehicleComponentSummaryItem.h new file mode 100644 index 0000000000000000000000000000000000000000..c9f1bed877a565c9ecc5f9ad82f954b7d60e48d1 --- /dev/null +++ b/src/VehicleSetup/VehicleComponentSummaryItem.h @@ -0,0 +1,57 @@ +/*===================================================================== + + QGroundControl Open Source Ground Control Station + + (c) 2009 - 2014 QGROUNDCONTROL PROJECT + + This file is part of the QGROUNDCONTROL project + + QGROUNDCONTROL is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + QGROUNDCONTROL is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with QGROUNDCONTROL. If not, see . + + ======================================================================*/ + +#ifndef VehicleComponentSummaryItem_H +#define VehicleComponentSummaryItem_H + +#include +#include +#include + +#include "UASInterface.h" + +/// @file +/// @brief Vehicle Component class. A vehicle component is an object which +/// abstracts the physical portion of a vehicle into a set of +/// configurable values and user interface. +/// @author Don Gagne + +class VehicleComponentSummaryItem : public QObject +{ + Q_OBJECT + + Q_PROPERTY(QString name READ name CONSTANT) + Q_PROPERTY(QString state READ state CONSTANT) + +public: + VehicleComponentSummaryItem(const QString& name, const QString& state, QObject* parent = NULL); + + QString name(void) const { return _name; } + QString state(void) const { return _state; } + +protected: + QString _name; + QString _state; +}; + +#endif diff --git a/src/test.qml b/src/test.qml new file mode 100644 index 0000000000000000000000000000000000000000..e623f499adfc735ab0cce6d26ce010c514d00375 --- /dev/null +++ b/src/test.qml @@ -0,0 +1,10 @@ +import QtQuick 2.2 +import QtQuick.Controls 1.2 +import QtQuick.Controls.Styles 1.2 +//import QGroundControl.FactControls 1.0 + +Row { +width: 200 +Text { id: firstCol; text: "Col 1" } +Text { horizontalAlignment: Text.AlignRight; width: parent.width - firstCol.contentWidth; text: "Col 2" } +}