Commit af38a105 authored by Don Gagne's avatar Don Gagne

Re-implemented Setup View

parent 1da6c502
......@@ -208,6 +208,8 @@ ReleaseBuild {
}
}
QML_IMPORT_PATH = $$BASEDIR/qml
# qextserialport should not be used by general QGroundControl code. Use QSerialPort instead. This is only
# here to support special case Firmware Upgrade code.
include(libs/qextserialport/src/qextserialport.pri)
......@@ -343,7 +345,7 @@ FORMS += \
src/ui/px4_configuration/PX4FirmwareUpgrade.ui \
src/ui/QGCUASFileView.ui \
src/QGCQmlWidgetHolder.ui \
src/ui/QGCMapRCToParamDialog.ui
src/ui/QGCMapRCToParamDialog.ui \
HEADERS += \
src/MG.h \
......@@ -713,13 +715,12 @@ FORMS += \
src/VehicleSetup/ParameterEditor.ui \
src/ui/QGCPX4VehicleConfig.ui \
src/AutoPilotPlugins/PX4/FlightModeConfig.ui \
src/VehicleSetup/SetupWidgetHolder.ui \
src/VehicleSetup/SetupView.ui \
HEADERS+= \
src/VehicleSetup/SetupView.h \
src/VehicleSetup/ParameterEditor.h \
src/VehicleSetup/VehicleComponent.h \
src/VehicleSetup/VehicleComponentSummaryItem.h \
src/AutoPilotPlugins/AutoPilotPluginManager.h \
src/AutoPilotPlugins/AutoPilotPlugin.h \
src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.h \
......@@ -733,13 +734,11 @@ HEADERS+= \
src/AutoPilotPlugins/PX4/SensorsComponent.h \
src/AutoPilotPlugins/PX4/SafetyComponent.h \
src/AutoPilotPlugins/PX4/PX4ParameterFacts.h \
src/VehicleSetup/SetupWidgetHolder.h \
SOURCES += \
src/VehicleSetup/SetupView.cc \
src/VehicleSetup/ParameterEditor.cc \
src/VehicleSetup/VehicleComponent.cc \
src/VehicleSetup/VehicleComponentSummaryItem.cc \
src/AutoPilotPlugins/AutoPilotPluginManager.cc \
src/AutoPilotPlugins/Generic/GenericAutoPilotPlugin.cc \
src/AutoPilotPlugins/Generic/GenericParameterFacts.cc \
......@@ -752,7 +751,6 @@ SOURCES += \
src/AutoPilotPlugins/PX4/SensorsComponent.cc \
src/AutoPilotPlugins/PX4/SafetyComponent.cc \
src/AutoPilotPlugins/PX4/PX4ParameterFacts.cc \
src/VehicleSetup/SetupWidgetHolder.cc \
# Fact System code
......
......@@ -241,19 +241,18 @@
<file alias="test.qml">src/test.qml</file>
<file alias="QGroundControl/FactControls/qmldir">qml/QGroundControl/FactControls/qmldir</file>
<file alias="QGroundControl/FactControls/SetupButton.qml">qml/QGroundControl/FactControls/SetupButton.qml</file>
<file alias="QGroundControl/FactControls/FactLabel.qml">qml/QGroundControl/FactControls/FactLabel.qml</file>
<file alias="QGroundControl/FactControls/FactTextField.qml">qml/QGroundControl/FactControls/FactTextField.qml</file>
<file alias="QGroundControl/FactControls/FactCheckBox.qml">qml/QGroundControl/FactControls/FactCheckBox.qml</file>
<file alias="QGroundControl/Controls/qmldir">qml/QGroundControl/Controls/qmldir</file>
<file alias="QGroundControl/Controls/SetupButton.qml">qml/QGroundControl/Controls/SetupButton.qml</file>
<file alias="octo_x.png">files/images/px4/airframes/octo_x.png</file>
<file alias="px4fmu_2.x.png">files/images/px4/boards/px4fmu_2.x.png</file>
<file alias="SetupViewConnected.qml">src/VehicleSetup/SetupViewConnected.qml</file>
<file alias="SetupViewDisconnected.qml">src/VehicleSetup/SetupViewDisconnected.qml</file>
<file alias="SetupPane.qml">src/VehicleSetup/SetupPane.qml</file>
<file alias="SetupViewButtons.qml">src/VehicleSetup/SetupViewButtons.qml</file>
<file alias="VehicleSummary.qml">src/VehicleSetup/VehicleSummary.qml</file>
<file alias="SafetyComponent.qml">src/AutoPilotPlugins/PX4/SafetyComponent.qml</file>
......@@ -263,6 +262,8 @@
<file alias="FlightModesComponentSummary.qml">src/AutoPilotPlugins/PX4/FlightModesComponentSummary.qml</file>
<file alias="AirframeComponentSummary.qml">src/AutoPilotPlugins/PX4/AirframeComponentSummary.qml</file>
<file alias="QGroundControl/Controls/setupButtonImage.png">files/Setup/cogwheels.png</file>
</qresource>
<qresource prefix="/AutoPilotPlugins/PX4">
......
import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
import QtGraphicalEffects 1.0
import QGroundControl.FactSystem 1.0
Button {
checkable: true
height: 80
text: "Button"
property bool setupComplete: true
property bool setupIndicator: true
style: ButtonStyle {
id: buttonStyle
property var __qgcpal: QGCPalette {
colorGroup: control.enabled ? QGCPalette.Active : QGCPalette.Disabled
}
background: Rectangle {
id: innerRect
readonly property real titleHeight: 30
border.color: control.checked ? "#eee333" : "#676767"
radius: 10
color: control.checked ? "#eee333" : "#343434"
Text {
id: titleBar
width: parent.width
height: parent.titleHeight
verticalAlignment: TextEdit.AlignVCenter
horizontalAlignment: TextEdit.AlignHCenter
text: control.text
font.pixelSize: 12
color: control.checked ? "black" : "white"
Rectangle {
id: setupIndicator
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.setupIndicator ? (control.setupComplete ? "green" : "red") : innerRect.color
}
}
Rectangle {
width: parent.width
height: parent.height - parent.titleHeight
y: parent.titleHeight
color: __qgcpal.window
border.color: control.checked ? "#eee333" : "#676767"
Image {
id: buttonImage
source: "setupButtonImage.png"
sourceSize: Qt.size(parent.width - 20, parent.height - 20)
anchors.horizontalCenter: parent.horizontalCenter
anchors.verticalCenter: parent.verticalCenter
smooth: true
visible: false
}
ColorOverlay {
anchors.fill: buttonImage
source: buttonImage
color: control.checked ? "#eee333" : "#58585a"
}
}
}
label: Item {}
}
}
Module QGroundControl.Controls
SetupButton 1.0 SetupButton.qml
\ No newline at end of file
......@@ -25,13 +25,14 @@
/// @author Don Gagne <don@thegagnes.com>
#include "SetupView.h"
#include "ui_SetupView.h"
#include "UASManager.h"
#include "AutoPilotPluginManager.h"
#include "VehicleComponent.h"
#include "PX4FirmwareUpgrade.h"
#include "ParameterEditor.h"
#include "SetupWidgetHolder.h"
#include "QGCQmlWidgetHolder.h"
#include "MainWindow.h"
#include "QGCMessageBox.h"
......@@ -40,16 +41,38 @@
#include <QDebug>
SetupView::SetupView(QWidget* parent) :
QGCQuickWidget(parent),
QWidget(parent),
_uasCurrent(NULL),
_initComplete(false),
_autoPilotPlugin(NULL)
_autoPilotPlugin(NULL),
_currentSetupWidget(NULL),
_ui(new Ui::SetupView)
{
_ui->setupUi(this);
bool fSucceeded = connect(UASManager::instance(), SIGNAL(activeUASSet(UASInterface*)), this, SLOT(_setActiveUAS(UASInterface*)));
Q_UNUSED(fSucceeded);
Q_ASSERT(fSucceeded);
setResizeMode(SizeRootObjectToView);
//setResizeMode(SizeRootObjectToView);
_ui->buttonHolder->setAutoPilot(NULL);
_ui->buttonHolder->setSource(QUrl::fromUserInput("qrc:/qml/SetupViewButtons.qml"));
QObject* rootObject = (QObject*)_ui->buttonHolder->rootObject();
Q_ASSERT(rootObject);
fSucceeded = connect(rootObject, SIGNAL(setupButtonClicked(QVariant)), this, SLOT(_setupButtonClicked(QVariant)));
Q_ASSERT(fSucceeded);
fSucceeded = connect(rootObject, SIGNAL(firmwareButtonClicked()), this, SLOT(_firmwareButtonClicked()));
Q_ASSERT(fSucceeded);
fSucceeded = connect(rootObject, SIGNAL(parametersButtonClicked()), this, SLOT(_parametersButtonClicked()));
Q_ASSERT(fSucceeded);
fSucceeded = connect(rootObject, SIGNAL(summaryButtonClicked()), this, SLOT(_summaryButtonClicked()));
Q_ASSERT(fSucceeded);
_setActiveUAS(UASManager::instance()->getActiveUAS());
}
......@@ -63,10 +86,16 @@ void SetupView::_setActiveUAS(UASInterface* uas)
{
if (_uasCurrent) {
Q_ASSERT(_autoPilotPlugin);
disconnect(_autoPilotPlugin);
_autoPilotPlugin = NULL;
disconnect(_autoPilotPlugin, &AutoPilotPlugin::pluginReady, this, &SetupView::_pluginReady);
}
_autoPilotPlugin = NULL;
_ui->buttonHolder->setAutoPilot(NULL);
_firmwareButtonClicked();
QObject* button = _ui->buttonHolder->rootObject()->findChild<QObject*>("firmwareButton");
Q_ASSERT(button);
button->setProperty("checked", true);
_uasCurrent = uas;
if (_uasCurrent) {
......@@ -74,48 +103,27 @@ void SetupView::_setActiveUAS(UASInterface* uas)
connect(_autoPilotPlugin, &AutoPilotPlugin::pluginReady, this, &SetupView::_pluginReady);
if (_autoPilotPlugin->pluginIsReady()) {
_setConnectedView();
_pluginReady();
}
} else {
_setDisconnectedView();
}
}
void SetupView::_pluginReady(void)
{
_setConnectedView();
}
void SetupView::_setViewConnections(void)
{
QObject*button = rootObject()->findChild<QObject*>("firmwareButton");
_ui->buttonHolder->setAutoPilot(_autoPilotPlugin);
_summaryButtonClicked();
QObject* button = _ui->buttonHolder->rootObject()->findChild<QObject*>("summaryButton");
Q_ASSERT(button);
connect(button, SIGNAL(clicked()), this, SLOT(_firmwareButtonClicked()));
button = rootObject()->findChild<QObject*>("parametersButton");
if (button) {
connect(button, SIGNAL(clicked()), this, SLOT(_parametersButtonClicked()));
}
button->setProperty("checked", true);
}
void SetupView::_setDisconnectedView(void)
void SetupView::_changeSetupWidget(QWidget* newWidget)
{
setSource(QUrl::fromUserInput("qrc:qml/SetupViewDisconnected.qml"));
_setViewConnections();
}
void SetupView::_setConnectedView(void)
{
Q_ASSERT(_uasCurrent);
Q_ASSERT(_autoPilotPlugin);
setAutoPilot(_autoPilotPlugin);
setSource(QUrl::fromUserInput("qrc:qml/SetupViewConnected.qml"));
disconnect(_autoPilotPlugin);
_setViewConnections();
connect((QObject*)rootObject(), SIGNAL(buttonClicked(QVariant)), this, SLOT(_setupButtonClicked(QVariant)));
if (_currentSetupWidget) {
delete _currentSetupWidget;
}
_currentSetupWidget = newWidget;
_ui->setupWidgetLayout->addWidget(newWidget);
}
void SetupView::_firmwareButtonClicked(void)
......@@ -125,24 +133,27 @@ void SetupView::_firmwareButtonClicked(void)
return;
}
SetupWidgetHolder* dialog = new SetupWidgetHolder(MainWindow::instance());
dialog->setModal(true);
dialog->setWindowTitle("Firmware Upgrade");
PX4FirmwareUpgrade* setup = new PX4FirmwareUpgrade(dialog);
dialog->setInnerWidget(setup);
dialog->exec();
PX4FirmwareUpgrade* setup = new PX4FirmwareUpgrade(this);
_changeSetupWidget(setup);
}
void SetupView::_parametersButtonClicked(void)
{
SetupWidgetHolder* dialog = new SetupWidgetHolder(MainWindow::instance());
dialog->setModal(true);
dialog->setWindowTitle("Parameter Editor");
ParameterEditor* setup = new ParameterEditor(_uasCurrent, QStringList(), this);
_changeSetupWidget(setup);
}
void SetupView::_summaryButtonClicked(void)
{
Q_ASSERT(_autoPilotPlugin);
ParameterEditor* setup = new ParameterEditor(_uasCurrent, QStringList(), dialog);
dialog->setInnerWidget(setup);
dialog->exec();
QGCQmlWidgetHolder* summary = new QGCQmlWidgetHolder;
Q_CHECK_PTR(summary);
summary->setAutoPilot(_autoPilotPlugin);
summary->setSource(QUrl::fromUserInput("qrc:/qml/VehicleSummary.qml"));
_changeSetupWidget(summary);
}
void SetupView::_setupButtonClicked(const QVariant& component)
......@@ -161,15 +172,5 @@ void SetupView::_setupButtonClicked(const QVariant& component)
return;
}
SetupWidgetHolder dialog(MainWindow::instance());
dialog.setModal(true);
dialog.setWindowTitle(vehicle->name());
QWidget* setupWidget = vehicle->setupWidget();
dialog.resize(setupWidget->minimumSize());
dialog.setInnerWidget(setupWidget);
dialog.exec();
delete setupWidget;
_changeSetupWidget(vehicle->setupWidget());
}
......@@ -24,18 +24,22 @@
#ifndef SETUPVIEW_H
#define SETUPVIEW_H
#include "UASInterface.h"
#include "ParameterEditor.h"
#include "VehicleComponent.h"
#include "QGCQuickWidget.h"
#include "AutoPilotPlugin.h"
#include <QWidget>
/// @file
/// @brief This class is used to display the UI for the VehicleComponent objects.
/// @author Don Gagne <don@thegagnes.com>
class SetupView : public QGCQuickWidget
namespace Ui {
class SetupView;
}
class SetupView : public QWidget
{
Q_OBJECT
......@@ -48,16 +52,18 @@ private slots:
void _pluginReady(void);
void _firmwareButtonClicked(void);
void _parametersButtonClicked(void);
void _summaryButtonClicked(void);
void _setupButtonClicked(const QVariant& component);
private:
void _setConnectedView(void);
void _setDisconnectedView(void);
void _setViewConnections(void);
void _changeSetupWidget(QWidget* newWidget);
UASInterface* _uasCurrent; ///< Currently active UAS
bool _initComplete; ///< true: parameters are ready and ui has been setup
AutoPilotPlugin* _autoPilotPlugin;
QWidget* _currentSetupWidget;
Ui::SetupView* _ui;
};
#endif
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SetupView</class>
<widget class="QWidget" name="SetupView">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>946</width>
<height>821</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<layout class="QHBoxLayout" name="horizontalLayout">
<item>
<widget class="QGCQuickWidget" name="buttonHolder">
<property name="sizePolicy">
<sizepolicy hsizetype="Fixed" vsizetype="Preferred">
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
</property>
<property name="minimumSize">
<size>
<width>160</width>
<height>0</height>
</size>
</property>
<property name="maximumSize">
<size>
<width>160</width>
<height>16777215</height>
</size>
</property>
<property name="resizeMode">
<enum>QGCQuickWidget::SizeRootObjectToView</enum>
</property>
</widget>
</item>
<item>
<widget class="QWidget" name="setupWidget">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QVBoxLayout" name="setupWidgetLayout"/>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
</item>
</layout>
</widget>
<customwidgets>
<customwidget>
<class>QGCQuickWidget</class>
<extends>QQuickWidget</extends>
<header>QGCQuickWidget.h</header>
<container>1</container>
</customwidget>
</customwidgets>
<resources/>
<connections/>
</ui>
import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
import QGroundControl.FactSystem 1.0
import QGroundControl.Controls 1.0
Rectangle {
id: topLevel
QGCPalette { id: palette; colorGroup: QGCPalette.Active }
color: palette.window
signal firmwareButtonClicked;
signal summaryButtonClicked;
signal parametersButtonClicked;
signal setupButtonClicked(variant component);
ExclusiveGroup { id: setupButtonGroup }
Component {
id: disconnectedButtons
Column {
spacing: 10
SetupButton {
id: firmwareButton; objectName: "firmwareButton"
width: parent.width
text: "FIRMWARE"
setupIndicator: false
exclusiveGroup: setupButtonGroup
onClicked: topLevel.firmwareButtonClicked()
}
}
}
Component {
id: connectedButtons
Column {
spacing: 10
SetupButton {
id: summaryButton; objectName: "summaryButton"
width: parent.width
text: "VEHICLE SUMMARY"
setupIndicator: false
exclusiveGroup: setupButtonGroup
onClicked: topLevel.summaryButtonClicked()
}
SetupButton {
id: firmwareButton; objectName: "firmwareButton"
width: parent.width
text: "FIRMWARE"
setupIndicator: false
exclusiveGroup: setupButtonGroup
onClicked: topLevel.firmwareButtonClicked()
}
Repeater {
model: autopilot.components
SetupButton {
width: parent.width
text: modelData.name.toUpperCase()
setupComplete: modelData.setupComplete
exclusiveGroup: setupButtonGroup
onClicked: topLevel.setupButtonClicked(modelData)
}
}
SetupButton {
width: parent.width
text: "PARAMETERS"
setupIndicator: false
exclusiveGroup: setupButtonGroup
onClicked: topLevel.parametersButtonClicked()
}
}
}
Loader {
anchors.fill: parent
sourceComponent: autopilot ? connectedButtons : disconnectedButtons
}
}
<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
<class>SetupWidgetHolder</class>
<widget class="QDialog" name="SetupWidgetHolder">
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>400</width>
<height>300</height>
</rect>
</property>
<property name="windowTitle">
<string>Form</string>
</property>
<property name="autoFillBackground">
<bool>true</bool>
</property>
<layout class="QVBoxLayout" name="verticalLayout_2">
<item>
<layout class="QVBoxLayout" name="setupWidgetLayout"/>
</item>
<item>
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>40</height>
</size>
</property>
</spacer>
</item>
</layout>
</widget>
<resources/>
<connections/>
</ui>
......@@ -4,34 +4,29 @@ import QtQuick.Controls.Styles 1.2
import QGroundControl.FactSystem 1.0
Rectangle {
width: 600
height: 400
QGCPalette { id: palette; colorGroup: QGCPalette.Active }
id: topLevel
objectName: "topLevel"
color: palette.window
signal buttonClicked(variant component);
Image {
anchors.fill: parent
fillMode: Image.PreserveAspectFit
smooth: true
source: autopilot.setupBackgroundImage;
}
Column {
anchors.margins: 20
anchors.fill: parent
spacing: 5
Rectangle { id: header; color: "lightblue"; radius: 10.0; width: parent.width; height: titleText.height + 20; opacity: 0.8;
Text { id: titleText; anchors.centerIn: parent; font.pointSize: 24; text: "Vehicle Setup" }
}
Flow {
width: parent.width;
height: parent.height - header.height - footer.height
height: parent.height
spacing: 5
Repeater {
......@@ -54,9 +49,8 @@ Rectangle {
border.color: "#888"
radius: 10
color: control.activeFocus ? "#47b" : "white"
opacity: control.hovered || control.activeFocus ? 1 : 0.8
Behavior on opacity {NumberAnimation{ duration: 100 }}
color: "white"
opacity: 0.8
Text {
id: titleBar
......@@ -108,23 +102,8 @@ Rectangle {
label: Item {}
}
onClicked: topLevel.buttonClicked(modelData)
}
}
}
Rectangle { id: footer; color: "lightblue"; radius: 10.0; width: parent.width; height: titleText.height + 20; opacity: 0.8;
property real spacing: (width - firmwareButton.width - parametersButton.width) / 3
Button { id: firmwareButton; objectName: "firmwareButton";
x: parent.spacing; anchors.verticalCenter: parent.verticalCenter;
text: "Firmware Upgrade" }
Button { id: parametersButton; objectName: "parametersButton"
x: firmwareButton.width + (parent.spacing*2); anchors.verticalCenter: parent.verticalCenter;
text: "Parameters" }
}
}
}
import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
//import QGroundControl.FactControls 1.0
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" }
Rectangle {
QGCPalette { id: palette; colorGroup: enabled ? QGCPalette.Active : QGCPalette.Disabled }