From 57c34c1cd048963c41c6890928d8f7c449d470ad Mon Sep 17 00:00:00 2001 From: Don Gagne Date: Thu, 15 Oct 2015 16:51:33 -0700 Subject: [PATCH] Convert all ui to a single Qml container --- QGCApplication.pro | 14 +- qgroundcontrol.qrc | 5 + src/AutoPilotPlugins/AutoPilotPlugin.cc | 4 +- src/FlightDisplay/FlightDisplayView.qml | 87 ++++-- ...View.cc => FlightDisplayViewController.cc} | 39 +-- ...ayView.h => FlightDisplayViewController.h} | 28 +- src/FlightMap/FlightMap.qml | 6 + src/MissionEditor/MissionEditor.qml | 262 ++++++++++-------- ...onEditor.cc => MissionEditorController.cc} | 82 +++--- ...sionEditor.h => MissionEditorController.h} | 13 +- src/QGCApplication.cc | 21 +- src/QGCFileDialog.cc | 1 + src/QGCMessageBox.h | 2 + src/QGCQmlWidgetHolder.cpp | 4 +- .../QGroundControl.Controls.qmldir | 3 + src/VehicleSetup/SetupView.cc | 97 ------- src/VehicleSetup/SetupView.h | 54 ---- src/VehicleSetup/SetupView.qml | 1 + src/VehicleSetup/SetupViewTest.cc | 27 +- src/VehicleSetup/SetupViewTest.h | 2 - src/qgcunittest/MainWindowTest.cc | 13 +- src/qgcunittest/MainWindowTest.h | 2 - src/ui/MainWindow.cc | 253 +++-------------- src/ui/MainWindow.h | 78 ++---- src/ui/MainWindow.qml | 106 +++++++ src/ui/QGCHilFlightGearConfiguration.cc | 3 +- src/ui/SettingsDialog.cc | 36 +-- src/ui/SettingsDialog.h | 7 - src/ui/SettingsDialog.ui | 74 ----- src/ui/toolbar/MainToolBar.qml | 172 ++++++------ ...ainToolBar.cc => MainToolBarController.cc} | 188 ++++--------- ...{MainToolBar.h => MainToolBarController.h} | 55 +--- src/ui/uas/UASMessageView.cc | 1 - 33 files changed, 625 insertions(+), 1115 deletions(-) rename src/FlightDisplay/{FlightDisplayView.cc => FlightDisplayViewController.cc} (68%) rename src/FlightDisplay/{FlightDisplayView.h => FlightDisplayViewController.h} (69%) rename src/MissionEditor/{MissionEditor.cc => MissionEditorController.cc} (81%) rename src/MissionEditor/{MissionEditor.h => MissionEditorController.h} (94%) delete mode 100644 src/VehicleSetup/SetupView.cc delete mode 100644 src/VehicleSetup/SetupView.h create mode 100644 src/ui/MainWindow.qml rename src/ui/toolbar/{MainToolBar.cc => MainToolBarController.cc} (63%) rename src/ui/toolbar/{MainToolBar.h => MainToolBarController.h} (71%) diff --git a/QGCApplication.pro b/QGCApplication.pro index 12fc55ae6..68453c50e 100644 --- a/QGCApplication.pro +++ b/QGCApplication.pro @@ -216,7 +216,7 @@ HEADERS += \ src/comm/TCPLink.h \ src/comm/UDPLink.h \ src/FlightDisplay/FlightDisplayWidget.h \ - src/FlightDisplay/FlightDisplayView.h \ + src/FlightDisplay/FlightDisplayViewController.h \ src/FlightMap/FlightMapSettings.h \ src/GAudioOutput.h \ src/HomePositionManager.h \ @@ -224,7 +224,7 @@ HEADERS += \ src/Joystick/JoystickManager.h \ src/LogCompressor.h \ src/MG.h \ - src/MissionEditor/MissionEditor.h \ + src/MissionEditor/MissionEditorController.h \ src/MissionManager/MissionManager.h \ src/QGC.h \ src/QGCApplication.h \ @@ -264,7 +264,7 @@ HEADERS += \ src/ui/QGCTCPLinkConfiguration.h \ src/ui/QGCUDPLinkConfiguration.h \ src/ui/SettingsDialog.h \ - src/ui/toolbar/MainToolBar.h \ + src/ui/toolbar/MainToolBarController.h \ src/ui/uas/QGCUnconnectedInfoWidget.h \ src/ui/uas/UASMessageView.h \ src/MissionItem.h \ @@ -327,7 +327,7 @@ SOURCES += \ src/comm/TCPLink.cc \ src/comm/UDPLink.cc \ src/FlightDisplay/FlightDisplayWidget.cc \ - src/FlightDisplay/FlightDisplayView.cc \ + src/FlightDisplay/FlightDisplayViewController.cc \ src/FlightMap/FlightMapSettings.cc \ src/GAudioOutput.cc \ src/HomePositionManager.cc \ @@ -335,7 +335,7 @@ SOURCES += \ src/Joystick/JoystickManager.cc \ src/LogCompressor.cc \ src/main.cc \ - src/MissionEditor/MissionEditor.cc \ + src/MissionEditor/MissionEditorController.cc \ src/MissionManager/MissionManager.cc \ src/QGC.cc \ src/QGCApplication.cc \ @@ -369,7 +369,7 @@ SOURCES += \ src/ui/QGCTCPLinkConfiguration.cc \ src/ui/QGCUDPLinkConfiguration.cc \ src/ui/SettingsDialog.cc \ - src/ui/toolbar/MainToolBar.cc \ + src/ui/toolbar/MainToolBarController.cc \ src/ui/uas/QGCUnconnectedInfoWidget.cc \ src/ui/uas/UASMessageView.cc \ src/MissionItem.cc \ @@ -518,7 +518,6 @@ HEADERS+= \ src/FirmwarePlugin/PX4/PX4FirmwarePlugin.h \ src/Vehicle/MultiVehicleManager.h \ src/Vehicle/Vehicle.h \ - src/VehicleSetup/SetupView.h \ src/VehicleSetup/VehicleComponent.h \ !MobileBuild { @@ -557,7 +556,6 @@ SOURCES += \ src/FirmwarePlugin/PX4/PX4FirmwarePlugin.cc \ src/Vehicle/MultiVehicleManager.cc \ src/Vehicle/Vehicle.cc \ - src/VehicleSetup/SetupView.cc \ src/VehicleSetup/VehicleComponent.cc \ !MobileBuild { diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index d641a9ef2..788b6aa60 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -119,6 +119,11 @@ src/QmlControls/QGCCanvas.qml src/QmlControls/ExclusiveGroupItem.qml + + src/ui/MainWindow.qml + src/ui/toolbar/MainToolBar.qml + src/FlightDisplay/FlightDisplayView.qml + src/VehicleSetup/SetupView.qml src/VehicleSetup/VehicleSummary.qml diff --git a/src/AutoPilotPlugins/AutoPilotPlugin.cc b/src/AutoPilotPlugins/AutoPilotPlugin.cc index 142643a9f..1613dd2ac 100644 --- a/src/AutoPilotPlugins/AutoPilotPlugin.cc +++ b/src/AutoPilotPlugins/AutoPilotPlugin.cc @@ -64,9 +64,7 @@ void AutoPilotPlugin::_parametersReadyChanged(bool parametersReady) QGCMessageBox::warning("Setup", "One or more vehicle components require setup prior to flight."); // Take the user to Vehicle Summary - MainWindow* mainWindow = MainWindow::instance(); - Q_ASSERT(mainWindow); - mainWindow->getMainToolBar()->onSetupView(); + MainWindow::instance()->showSetupView(); qgcApp()->processEvents(QEventLoop::ExcludeUserInputEvents); } } diff --git a/src/FlightDisplay/FlightDisplayView.qml b/src/FlightDisplay/FlightDisplayView.qml index f0159577d..2731316e8 100644 --- a/src/FlightDisplay/FlightDisplayView.qml +++ b/src/FlightDisplay/FlightDisplayView.qml @@ -34,11 +34,23 @@ import QGroundControl.ScreenTools 1.0 import QGroundControl.Controls 1.0 import QGroundControl.Palette 1.0 import QGroundControl.Vehicle 1.0 +import QGroundControl.Controllers 1.0 /// Flight Display View Item { id: root + // Top margin for all widgets. Used to prevent overlap with the toolbar + property real topMargin: 0 + + // Used by parent to hide widgets when it displays something above in the z order. + // Prevents z order drawing problems. + property bool hideWidgets: false + + readonly property alias zOrderTopMost: flightMap.zOrderTopMost + readonly property alias zOrderWidgets: flightMap.zOrderWidgets + readonly property alias zOrderMapItems: flightMap.zOrderMapItems + property var __qgcPal: QGCPalette { colorGroupEnabled: enabled } property var _activeVehicle: multiVehicleManager.activeVehicle @@ -70,6 +82,8 @@ Item { property bool _showMap: getBool(QGroundControl.flightMapSettings.loadMapSetting(flightMap.mapName, _showMapBackgroundKey, "1")) + FlightDisplayViewController { id: _controller; } + ExclusiveGroup { id: _dropButtonsExclusiveGroup } @@ -86,7 +100,7 @@ Item { } function _setShowMap(showMap) { - _showMap = flightDisplay.hasVideo ? showMap : true + _showMap = _controller.hasVideo ? showMap : true QGroundControl.flightMapSettings.saveMapSetting(flightMap.mapName, _showMapBackgroundKey, setBool(_showMap)) } @@ -118,6 +132,7 @@ Item { label: "H" coordinate: (_activeVehicle && _activeVehicle.homePositionAvailable) ? _activeVehicle.homePosition : QtPositioning.coordinate(0, 0) visible: _activeVehicle ? _activeVehicle.homePositionAvailable : false + z: flightMap.zOrderMapItems } // Add trajectory points to the map @@ -128,6 +143,8 @@ Item { MapPolyline { line.width: 3 line.color: "orange" + z: flightMap.zOrderMapItems - 1 + path: [ { latitude: object.coordinate1.latitude, longitude: object.coordinate1.longitude }, @@ -145,6 +162,7 @@ Item { vehicle: object coordinate: object.coordinate isSatellite: flightMap.isSatelliteMap + z: flightMap.zOrderMapItems } } @@ -157,6 +175,7 @@ Item { label: object.sequenceNumber isCurrentItem: object.isCurrentItem coordinate: object.coordinate + z: flightMap.zOrderMapItems } } @@ -175,17 +194,20 @@ Item { horizontalAlignment: Text.AlignHCenter visible: object.satelliteLock < 2 text: "No GPS Lock for Vehicle #" + object.id + z: flightMap.zOrderMapItems - 2 } } } QGCCompassWidget { - anchors.margins: ScreenTools.defaultFontPixelHeight + anchors.leftMargin: ScreenTools.defaultFontPixelHeight + anchors.topMargin: topMargin anchors.left: parent.left anchors.top: parent.top size: ScreenTools.defaultFontPixelSize * (13.3) heading: _heading active: multiVehicleManager.activeVehicleAvailable + z: flightMap.zOrderWidgets } QGCAttitudeWidget { @@ -196,6 +218,7 @@ Item { rollAngle: _roll pitchAngle: _pitch active: multiVehicleManager.activeVehicleAvailable + z: flightMap.zOrderWidgets } DropButton { @@ -207,6 +230,7 @@ Item { buttonImage: "/qmlimages/MapCenter.svg" viewportMargins: ScreenTools.defaultFontPixelWidth / 2 exclusiveGroup: _dropButtonsExclusiveGroup + z: flightMap.zOrderWidgets dropDownComponent: Component { Row { @@ -242,14 +266,16 @@ Item { } DropButton { - id: mapTypeButton - anchors.margins: ScreenTools.defaultFontPixelHeight - anchors.top: parent.top - anchors.right: parent.right - dropDirection: dropDown - buttonImage: "/qmlimages/MapType.svg" - viewportMargins: ScreenTools.defaultFontPixelWidth / 2 - exclusiveGroup: _dropButtonsExclusiveGroup + id: mapTypeButton + anchors.topMargin: topMargin + anchors.rightMargin: ScreenTools.defaultFontPixelHeight + anchors.top: parent.top + anchors.right: parent.right + dropDirection: dropDown + buttonImage: "/qmlimages/MapType.svg" + viewportMargins: ScreenTools.defaultFontPixelWidth / 2 + exclusiveGroup: _dropButtonsExclusiveGroup + z: flightMap.zOrderWidgets dropDownComponent: Component { Row { @@ -277,8 +303,8 @@ Item { QGCVideoBackground { anchors.fill: parent - display: videoDisplay - receiver: videoReceiver + display: _controller.videoSurface + receiver: _controller.videoReceiver visible: !_showMap QGCCompassHUD { @@ -289,7 +315,7 @@ Item { height: ScreenTools.defaultFontPixelSize * (10) heading: _heading active: multiVehicleManager.activeVehicleAvailable - z: 70 + z: flightMap.zOrderWidgets } QGCAttitudeHUD { @@ -299,6 +325,7 @@ Item { width: ScreenTools.defaultFontPixelSize * (30) height: ScreenTools.defaultFontPixelSize * (30) active: multiVehicleManager.activeVehicleAvailable + z: flightMap.zOrderWidgets } } @@ -307,7 +334,8 @@ Item { height: parent.height * 0.65 > ScreenTools.defaultFontPixelSize * (23.4) ? ScreenTools.defaultFontPixelSize * (23.4) : parent.height * 0.65 width: ScreenTools.defaultFontPixelSize * (5) altitude: _altitudeWGS84 - z: 30 + z: flightMap.zOrderWidgets + visible: !hideWidgets } QGCSpeedWidget { @@ -315,7 +343,8 @@ Item { width: ScreenTools.defaultFontPixelSize * (5) height: parent.height * 0.65 > ScreenTools.defaultFontPixelSize * (23.4) ? ScreenTools.defaultFontPixelSize * (23.4) : parent.height * 0.65 speed: _groundSpeed - z: 40 + z: flightMap.zOrderWidgets + visible: !hideWidgets } QGCCurrentSpeed { @@ -324,7 +353,8 @@ Item { airspeed: _airSpeed groundspeed: _groundSpeed active: multiVehicleManager.activeVehicleAvailable - z: 50 + z: flightMap.zOrderWidgets + visible: !hideWidgets } QGCCurrentAltitude { @@ -333,7 +363,8 @@ Item { altitude: _altitudeWGS84 vertZ: _climbRate active: multiVehicleManager.activeVehicleAvailable - z: 60 + z: flightMap.zOrderWidgets + visible: !hideWidgets } // Mission item list @@ -348,6 +379,8 @@ Item { opacity: 0.75 orientation: ListView.Horizontal model: multiVehicleManager.activeVehicle ? multiVehicleManager.activeVehicle.missionItems : 0 + z: flightMap.zOrderWidgets + visible: !hideWidgets property real _maxItemHeight: 0 @@ -360,12 +393,14 @@ Item { QGCButton { - id: optionsButton - x: flightMap.mapWidgets.x - y: flightMap.mapWidgets.y - height - (ScreenTools.defaultFontPixelHeight / 2) - width: flightMap.mapWidgets.width - text: "Options" - menu: optionsMenu + id: optionsButton + x: flightMap.mapWidgets.x + y: flightMap.mapWidgets.y - height - (ScreenTools.defaultFontPixelHeight / 2) + z: flightMap.zOrderWidgets + width: flightMap.mapWidgets.width + text: "Options" + menu: optionsMenu + visible: _controller.hasVideo && !hideWidgets ExclusiveGroup { id: backgroundTypeGroup @@ -380,7 +415,6 @@ Item { checkable: true checked: _showMap text: "Show map as background" - visible: flightDisplay.hasVideo onTriggered: _setShowMap(true) } @@ -391,14 +425,9 @@ Item { checkable: true checked: !_showMap text: "Show video as background" - visible: flightDisplay.hasVideo onTriggered: _setShowMap(false) } - - MenuSeparator { - visible: flightDisplay.hasVideo && _showMap - } } } } diff --git a/src/FlightDisplay/FlightDisplayView.cc b/src/FlightDisplay/FlightDisplayViewController.cc similarity index 68% rename from src/FlightDisplay/FlightDisplayView.cc rename to src/FlightDisplay/FlightDisplayViewController.cc index 2d4d4cec8..c0ff3de87 100644 --- a/src/FlightDisplay/FlightDisplayView.cc +++ b/src/FlightDisplay/FlightDisplayViewController.cc @@ -26,30 +26,15 @@ This file is part of the QGROUNDCONTROL project #include #include -#include -#include "VideoReceiver.h" #include "ScreenToolsController.h" -#include "FlightDisplayView.h" +#include "FlightDisplayViewController.h" -const char* kMainFlightDisplayViewGroup = "FlightDisplayView"; +const char* kMainFlightDisplayViewControllerGroup = "FlightDisplayViewController"; -FlightDisplayView::FlightDisplayView(QWidget *parent) - : QGCQmlWidgetHolder(QString(), NULL, parent) +FlightDisplayViewController::FlightDisplayViewController(QObject *parent) + : QObject(parent) { - setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); - setObjectName("FlightDisplayView"); - // Get rid of layout default margins - QLayout* pl = layout(); - if(pl) { - pl->setContentsMargins(0,0,0,0); - } -#ifndef __android__ - setMinimumWidth( 31 * ScreenToolsController::defaultFontPixelSize_s()); - setMinimumHeight(33 * ScreenToolsController::defaultFontPixelSize_s()); -#endif - setContextPropertyObject("flightDisplay", this); - /* * This is the receiving end of an UDP RTP stream. The sender can be setup with this command: * @@ -75,19 +60,15 @@ FlightDisplayView::FlightDisplayView(QWidget *parent) * Do not change anything else unless you know what you are doing. Any other change will require a matching change on the receiving end. * */ - VideoSurface* pSurface = new VideoSurface; - setContextPropertyObject("videoDisplay", pSurface); - VideoReceiver* pReceiver = new VideoReceiver(this); - pReceiver->setUri(QLatin1Literal("udp://0.0.0.0:5000")); + _videoSurface = new VideoSurface; + _videoReceiver = new VideoReceiver(this); + _videoReceiver->setUri(QLatin1Literal("udp://0.0.0.0:5000")); #if defined(QGC_GST_STREAMING) - pReceiver->setVideoSink(pSurface->videoSink()); + _videoReceiver->setVideoSink(_videoSurface->videoSink()); #endif - setContextPropertyObject("videoReceiver", pReceiver); - - setSource(QUrl::fromUserInput("qrc:/qml/FlightDisplayView.qml")); - setVisible(true); } -FlightDisplayView::~FlightDisplayView() +FlightDisplayViewController::~FlightDisplayViewController() { + } diff --git a/src/FlightDisplay/FlightDisplayView.h b/src/FlightDisplay/FlightDisplayViewController.h similarity index 69% rename from src/FlightDisplay/FlightDisplayView.h rename to src/FlightDisplay/FlightDisplayViewController.h index 7fe374b2e..87accb71e 100644 --- a/src/FlightDisplay/FlightDisplayView.h +++ b/src/FlightDisplay/FlightDisplayViewController.h @@ -21,32 +21,36 @@ This file is part of the QGROUNDCONTROL project ======================================================================*/ -#ifndef FlightDisplayView_H -#define FlightDisplayView_H +#ifndef FlightDisplayViewController_H +#define FlightDisplayViewController_H -#include "QGCQmlWidgetHolder.h" +#include -class FlightDisplayView : public QGCQmlWidgetHolder +#include "VideoSurface.h" +#include "VideoReceiver.h" + +class FlightDisplayViewController : public QObject { Q_OBJECT -public: - FlightDisplayView(QWidget* parent = NULL); - ~FlightDisplayView(); - /// @brief Invokes the Flight Display Options menu - void showOptionsMenu() { emit showOptionsMenuChanged(); } +public: + FlightDisplayViewController(QObject* parent = NULL); + ~FlightDisplayViewController(); Q_PROPERTY(bool hasVideo READ hasVideo CONSTANT) + Q_PROPERTY(VideoSurface* videoSurface MEMBER _videoSurface CONSTANT); + Q_PROPERTY(VideoReceiver* videoReceiver MEMBER _videoReceiver CONSTANT); + #if defined(QGC_GST_STREAMING) bool hasVideo () { return true; } #else bool hasVideo () { return false; } #endif -signals: - void showOptionsMenuChanged (); - +private: + VideoSurface* _videoSurface; + VideoReceiver* _videoReceiver; }; #endif diff --git a/src/FlightMap/FlightMap.qml b/src/FlightMap/FlightMap.qml index dfa3e7984..3f1d1c028 100644 --- a/src/FlightMap/FlightMap.qml +++ b/src/FlightMap/FlightMap.qml @@ -55,6 +55,10 @@ Map { property real lon: (longitude >= -180 && longitude <= 180) ? longitude : 0 property real lat: (latitude >= -90 && latitude <= 90) ? latitude : 0 + readonly property real zOrderTopMost: 1000 ///< z order for top most items, toolbar, main window sub view + readonly property real zOrderWidgets: 100 ///< z order value to widgets, for example: zoom controls, hud widgetss + readonly property real zOrderMapItems: 50 ///< z order value for map items, for example: mission item indicators + zoomLevel: 18 center: QtPositioning.coordinate(lat, lon) gesture.flickDeceleration: 3000 @@ -115,6 +119,7 @@ Map { QGCButton { width: parent._buttonWidth + z: zOrderWidgets //iconSource: "/qmlimages/ZoomPlus.svg" text: "+" @@ -131,6 +136,7 @@ Map { QGCButton { width: parent._buttonWidth + z: zOrderWidgets //iconSource: "/qmlimages/ZoomMinus.svg" text: "-" diff --git a/src/MissionEditor/MissionEditor.qml b/src/MissionEditor/MissionEditor.qml index dc6216676..5107ef5ac 100644 --- a/src/MissionEditor/MissionEditor.qml +++ b/src/MissionEditor/MissionEditor.qml @@ -33,28 +33,34 @@ import QGroundControl.ScreenTools 1.0 import QGroundControl.Controls 1.0 import QGroundControl.Palette 1.0 import QGroundControl.Mavlink 1.0 +import QGroundControl.Controllers 1.0 /// Mission Editor QGCView { viewPanel: panel + // zOrder comes from the Loader in MainWindow.qml + z: zOrder + readonly property int _decimalPlaces: 7 readonly property real _horizontalMargin: ScreenTools.defaultFontPixelWidth / 2 readonly property real _verticalMargin: ScreenTools.defaultFontPixelHeight / 2 readonly property var _activeVehicle: multiVehicleManager.activeVehicle readonly property real _editFieldWidth: ScreenTools.defaultFontPixelWidth * 16 - property var _missionItems: controller.missionItems + property var _missionItems: _controller.missionItems property var _homePositionManager: QGroundControl.homePositionManager property string _homePositionName: _homePositionManager.homePositions.get(0).name property var offlineHomePosition: _homePositionManager.homePositions.get(0).coordinate - property var liveHomePosition: controller.liveHomePosition - property var liveHomePositionAvailable: controller.liveHomePositionAvailable + property var liveHomePosition: _controller.liveHomePosition + property var liveHomePositionAvailable: _controller.liveHomePositionAvailable property var homePosition: offlineHomePosition // live or offline depending on state + MissionEditorController { id: _controller } + QGCPalette { id: _qgcPal; colorGroupEnabled: enabled } ExclusiveGroup { @@ -86,7 +92,7 @@ QGCView { onLiveHomePositionChanged: updateHomePosition() Connections { - target: controller + target: _controller // When the mission items change _missionsItems[0] changes as well so we need to reset it to home onMissionItemsChanged: updateHomePosition @@ -123,7 +129,7 @@ QGCView { if (homePositionManagerButton.checked) { offlineHomePosition = coordinate } else if (addMissionItemsButton.checked) { - var index = controller.addMissionItem(coordinate) + var index = _controller.addMissionItem(coordinate) setCurrentItem(index) } } @@ -138,7 +144,7 @@ QGCView { border.color: "white" color: "black" opacity: 0.75 - visible: controller.missionItems.dirty + visible: _controller.missionItems.dirty QGCLabel { id: syncNeededText @@ -154,58 +160,61 @@ QGCView { } } - Row { - spacing: ScreenTools.defaultFontPixelWidth - anchors.top: parent.top - anchors.right: parent.right - anchors.margins: ScreenTools.defaultFontPixelWidth - - RoundButton { - id: addMissionItemsButton - buttonImage: "/qmlimages/MapAddMission.svg" - exclusiveGroup: _dropButtonsExclusiveGroup - } - - RoundButton { - id: homePositionManagerButton - buttonImage: "/qmlimages/MapHome.svg" - exclusiveGroup: _dropButtonsExclusiveGroup - } - - DropButton { - id: centerMapButton - dropDirection: dropDown - buttonImage: "/qmlimages/MapCenter.svg" - viewportMargins: ScreenTools.defaultFontPixelWidth / 2 - exclusiveGroup: _dropButtonsExclusiveGroup - - dropDownComponent: Component { - Row { - spacing: ScreenTools.defaultFontPixelWidth + RoundButton { + id: addMissionItemsButton + anchors.rightMargin: ScreenTools.defaultFontPixelWidth + anchors.right: homePositionManagerButton.left + anchors.top: helpButton.top + buttonImage: "/qmlimages/MapAddMission.svg" + exclusiveGroup: _dropButtonsExclusiveGroup + } - QGCButton { - text: "Home" + RoundButton { + id: homePositionManagerButton + anchors.rightMargin: ScreenTools.defaultFontPixelWidth + anchors.right: centerMapButton.left + anchors.top: helpButton.top + buttonImage: "/qmlimages/MapHome.svg" + exclusiveGroup: _dropButtonsExclusiveGroup + } - onClicked: { - centerMapButton.hideDropDown() - editorMap.center = QtPositioning.coordinate(homePosition.latitude, homePosition.longitude) - } + DropButton { + id: centerMapButton + anchors.rightMargin: ScreenTools.defaultFontPixelWidth + anchors.right: syncButton.left + anchors.top: helpButton.top + dropDirection: dropDown + buttonImage: "/qmlimages/MapCenter.svg" + viewportMargins: ScreenTools.defaultFontPixelWidth / 2 + exclusiveGroup: _dropButtonsExclusiveGroup + + dropDownComponent: Component { + Row { + spacing: ScreenTools.defaultFontPixelWidth + + QGCButton { + text: "Home" + + onClicked: { + centerMapButton.hideDropDown() + editorMap.center = QtPositioning.coordinate(homePosition.latitude, homePosition.longitude) } + } - QGCButton { - text: "Vehicle" - enabled: activeVehicle && activeVehicle.latitude != 0 && activeVehicle.longitude != 0 + QGCButton { + text: "Vehicle" + enabled: activeVehicle && activeVehicle.latitude != 0 && activeVehicle.longitude != 0 - property var activeVehicle: multiVehicleManager.activeVehicle + property var activeVehicle: multiVehicleManager.activeVehicle - onClicked: { - centerMapButton.hideDropDown() - editorMap.latitude = activeVehicle.latitude - editorMap.longitude = activeVehicle.longitude - } + onClicked: { + centerMapButton.hideDropDown() + editorMap.latitude = activeVehicle.latitude + editorMap.longitude = activeVehicle.longitude } + } - /* + /* This code will need to wait for Qml 5.5 support since Map.visibleRegion is only in Qt 5.5 @@ -240,104 +249,111 @@ QGCView { } } */ - } } } + } - DropButton { - id: syncButton - dropDirection: dropDown - buttonImage: "/qmlimages/MapSync.svg" - viewportMargins: ScreenTools.defaultFontPixelWidth / 2 - exclusiveGroup: _dropButtonsExclusiveGroup - - dropDownComponent: Component { - Row { - spacing: ScreenTools.defaultFontPixelWidth - - QGCButton { - text: "Load from vehicle" - enabled: _activeVehicle && !_activeVehicle.missionManager.inProgress - - onClicked: { - syncButton.hideDropDown() - controller.getMissionItems() - } + DropButton { + id: syncButton + anchors.rightMargin: ScreenTools.defaultFontPixelWidth + anchors.right: mapTypeButton.left + anchors.top: helpButton.top + dropDirection: dropDown + buttonImage: "/qmlimages/MapSync.svg" + viewportMargins: ScreenTools.defaultFontPixelWidth / 2 + exclusiveGroup: _dropButtonsExclusiveGroup + + dropDownComponent: Component { + Row { + spacing: ScreenTools.defaultFontPixelWidth + + QGCButton { + text: "Load from vehicle" + enabled: _activeVehicle && !_activeVehicle.missionManager.inProgress + + onClicked: { + syncButton.hideDropDown() + _controller.getMissionItems() } + } - QGCButton { - text: "Save to vehicle" - enabled: _activeVehicle && !_activeVehicle.missionManager.inProgress + QGCButton { + text: "Save to vehicle" + enabled: _activeVehicle && !_activeVehicle.missionManager.inProgress - onClicked: { - syncButton.hideDropDown() - controller.setMissionItems() - } + onClicked: { + syncButton.hideDropDown() + _controller.setMissionItems() } + } - QGCButton { - text: "Load from file..." + QGCButton { + text: "Load from file..." - onClicked: { - syncButton.hideDropDown() - controller.loadMissionFromFile() - } + onClicked: { + syncButton.hideDropDown() + _controller.loadMissionFromFile() } + } - QGCButton { - text: "Save to file..." + QGCButton { + text: "Save to file..." - onClicked: { - syncButton.hideDropDown() - controller.saveMissionToFile() - } + onClicked: { + syncButton.hideDropDown() + _controller.saveMissionToFile() } } } } + } - DropButton { - id: mapTypeButton - dropDirection: dropDown - buttonImage: "/qmlimages/MapType.svg" - viewportMargins: ScreenTools.defaultFontPixelWidth / 2 - exclusiveGroup: _dropButtonsExclusiveGroup + DropButton { + id: mapTypeButton + anchors.rightMargin: ScreenTools.defaultFontPixelWidth + anchors.right: helpButton.left + anchors.top: helpButton.top + dropDirection: dropDown + buttonImage: "/qmlimages/MapType.svg" + viewportMargins: ScreenTools.defaultFontPixelWidth / 2 + exclusiveGroup: _dropButtonsExclusiveGroup - dropDownComponent: Component { - Row { - spacing: ScreenTools.defaultFontPixelWidth + dropDownComponent: Component { + Row { + spacing: ScreenTools.defaultFontPixelWidth - Repeater { - model: QGroundControl.flightMapSettings.mapTypes - - QGCButton { - checkable: true - checked: editorMap.mapType == text - text: modelData - exclusiveGroup: _mapTypeButtonsExclusiveGroup - - onClicked: { - editorMap.mapType = text - checked = true - mapTypeButton.hideDropDown() - } + Repeater { + model: QGroundControl.flightMapSettings.mapTypes + + QGCButton { + checkable: true + checked: editorMap.mapType == text + text: modelData + exclusiveGroup: _mapTypeButtonsExclusiveGroup + + onClicked: { + editorMap.mapType = text + checked = true + mapTypeButton.hideDropDown() } } } } } + } - RoundButton { - id: helpButton - buttonImage: "/qmlimages/Help.svg" - exclusiveGroup: _dropButtonsExclusiveGroup - } - + RoundButton { + id: helpButton + anchors.margins: ScreenTools.defaultFontPixelWidth + anchors.right: parent.right + anchors.top: parent.top + buttonImage: "/qmlimages/Help.svg" + exclusiveGroup: _dropButtonsExclusiveGroup } // Add the mission items to the map MapItemView { - model: controller.missionItems + model: _controller.missionItems delegate: MissionItemIndicator { @@ -379,7 +395,7 @@ QGCView { // Add lines between waypoints MapItemView { - model: controller.waypointLines + model: _controller.waypointLines delegate: MapPolyline { @@ -432,7 +448,7 @@ QGCView { anchors.fill: parent spacing: _verticalMargin orientation: ListView.Vertical - model: controller.canEdit ? controller.missionItems : 0 + model: _controller.canEdit ? _controller.missionItems : 0 property real _maxItemHeight: 0 @@ -446,7 +462,7 @@ QGCView { onRemove: { var newCurrentItem = object.sequenceNumber - 1 - controller.removeMissionItem(object.sequenceNumber) + _controller.removeMissionItem(object.sequenceNumber) if (_missionItems.count > 1) { newCurrentItem = Math.min(_missionItems.count - 1, newCurrentItem) setCurrentItem(newCurrentItem) @@ -457,7 +473,7 @@ QGCView { QGCLabel { anchors.fill: parent - visible: !controller.canEdit + visible: !_controller.canEdit wrapMode: Text.WordWrap text: "The set of mission items you have loaded cannot be edited by QGroundControl. " + "You will only be able to save these to a file, or send them to a vehicle." diff --git a/src/MissionEditor/MissionEditor.cc b/src/MissionEditor/MissionEditorController.cc similarity index 81% rename from src/MissionEditor/MissionEditor.cc rename to src/MissionEditor/MissionEditorController.cc index 96397f7ea..a15a7f243 100644 --- a/src/MissionEditor/MissionEditor.cc +++ b/src/MissionEditor/MissionEditorController.cc @@ -21,7 +21,7 @@ This file is part of the QGROUNDCONTROL project ======================================================================*/ -#include "MissionEditor.h" +#include "MissionEditorController.h" #include "ScreenToolsController.h" #include "MultiVehicleManager.h" #include "MissionManager.h" @@ -32,46 +32,36 @@ This file is part of the QGROUNDCONTROL project #include #include -const char* MissionEditor::_settingsGroup = "MissionEditor"; +const char* MissionEditorController::_settingsGroup = "MissionEditorController"; -MissionEditor::MissionEditor(QWidget *parent) - : QGCQmlWidgetHolder(QString(), NULL, parent) +MissionEditorController::MissionEditorController(QWidget *parent) + : QObject(parent) , _missionItems(NULL) , _canEdit(true) , _activeVehicle(NULL) , _liveHomePositionAvailable(false) { - // Get rid of layout default margins - QLayout* pl = layout(); - if(pl) { - pl->setContentsMargins(0,0,0,0); - } - MultiVehicleManager* multiVehicleMgr = MultiVehicleManager::instance(); - connect(multiVehicleMgr, &MultiVehicleManager::activeVehicleChanged, this, &MissionEditor::_activeVehicleChanged); + connect(multiVehicleMgr, &MultiVehicleManager::activeVehicleChanged, this, &MissionEditorController::_activeVehicleChanged); Vehicle* activeVehicle = multiVehicleMgr->activeVehicle(); if (activeVehicle) { MissionManager* missionManager = activeVehicle->missionManager(); - connect(missionManager, &MissionManager::newMissionItemsAvailable, this, &MissionEditor::_newMissionItemsAvailable); + connect(missionManager, &MissionManager::newMissionItemsAvailable, this, &MissionEditorController::_newMissionItemsAvailable); _newMissionItemsAvailable(); _activeVehicleChanged(activeVehicle); } else { _missionItems = new QmlObjectListModel(this); _initAllMissionItems(); } - - setContextPropertyObject("controller", this); - - setSource(QUrl::fromUserInput("qrc:/qml/MissionEditor.qml")); } -MissionEditor::~MissionEditor() +MissionEditorController::~MissionEditorController() { } -void MissionEditor::_newMissionItemsAvailable(void) +void MissionEditorController::_newMissionItemsAvailable(void) { if (_missionItems) { _deinitAllMissionItems(); @@ -86,18 +76,18 @@ void MissionEditor::_newMissionItemsAvailable(void) _initAllMissionItems(); } -void MissionEditor::getMissionItems(void) +void MissionEditorController::getMissionItems(void) { Vehicle* activeVehicle = MultiVehicleManager::instance()->activeVehicle(); if (activeVehicle) { MissionManager* missionManager = activeVehicle->missionManager(); - connect(missionManager, &MissionManager::newMissionItemsAvailable, this, &MissionEditor::_newMissionItemsAvailable); + connect(missionManager, &MissionManager::newMissionItemsAvailable, this, &MissionEditorController::_newMissionItemsAvailable); activeVehicle->missionManager()->requestMissionItems(); } } -void MissionEditor::setMissionItems(void) +void MissionEditorController::setMissionItems(void) { // FIXME: Need to pull out home position Vehicle* activeVehicle = MultiVehicleManager::instance()->activeVehicle(); @@ -108,7 +98,7 @@ void MissionEditor::setMissionItems(void) } } -int MissionEditor::addMissionItem(QGeoCoordinate coordinate) +int MissionEditorController::addMissionItem(QGeoCoordinate coordinate) { if (!_canEdit) { qWarning() << "addMissionItem called with _canEdit == false"; @@ -128,7 +118,7 @@ int MissionEditor::addMissionItem(QGeoCoordinate coordinate) return _missionItems->count() - 1; } -void MissionEditor::removeMissionItem(int index) +void MissionEditorController::removeMissionItem(int index) { if (!_canEdit) { qWarning() << "addMissionItem called with _canEdit == false"; @@ -142,7 +132,7 @@ void MissionEditor::removeMissionItem(int index) _recalcAll(); } -void MissionEditor::loadMissionFromFile(void) +void MissionEditorController::loadMissionFromFile(void) { QString errorString; QString filename = QGCFileDialog::getOpenFileName(NULL, "Select Mission File to load"); @@ -196,7 +186,7 @@ void MissionEditor::loadMissionFromFile(void) _initAllMissionItems(); } -void MissionEditor::saveMissionToFile(void) +void MissionEditorController::saveMissionToFile(void) { QString errorString; QString filename = QGCFileDialog::getSaveFileName(NULL, "Select file to save mission to"); @@ -222,7 +212,7 @@ void MissionEditor::saveMissionToFile(void) _missionItems->setDirty(false); } -void MissionEditor::_recalcWaypointLines(void) +void MissionEditorController::_recalcWaypointLines(void) { bool firstCoordinateItem = true; MissionItem* lastCoordinateItem = qobject_cast(_missionItems->get(0)); @@ -253,7 +243,7 @@ void MissionEditor::_recalcWaypointLines(void) } // This will update the sequence numbers to be sequential starting from 0 -void MissionEditor::_recalcSequence(void) +void MissionEditorController::_recalcSequence(void) { MissionItem* currentParentItem = qobject_cast(_missionItems->get(0)); @@ -268,7 +258,7 @@ void MissionEditor::_recalcSequence(void) } // This will update the child item hierarchy -void MissionEditor::_recalcChildItems(void) +void MissionEditorController::_recalcChildItems(void) { MissionItem* currentParentItem = qobject_cast(_missionItems->get(0)); @@ -287,7 +277,7 @@ void MissionEditor::_recalcChildItems(void) } } -void MissionEditor::_recalcAll(void) +void MissionEditorController::_recalcAll(void) { _recalcSequence(); _recalcChildItems(); @@ -295,7 +285,7 @@ void MissionEditor::_recalcAll(void) } /// Initializes a new set of mission items which may have come from the vehicle or have been loaded from a file -void MissionEditor::_initAllMissionItems(void) +void MissionEditorController::_initAllMissionItems(void) { // Add the home position item to the front MissionItem* homeItem = new MissionItem(this); @@ -317,45 +307,45 @@ void MissionEditor::_initAllMissionItems(void) _missionItems->setDirty(false); } -void MissionEditor::_deinitAllMissionItems(void) +void MissionEditorController::_deinitAllMissionItems(void) { for (int i=0; i<_missionItems->count(); i++) { _deinitMissionItem(qobject_cast(_missionItems->get(i))); } } -void MissionEditor::_initMissionItem(MissionItem* item) +void MissionEditorController::_initMissionItem(MissionItem* item) { _missionItems->setDirty(false); - connect(item, &MissionItem::commandChanged, this, &MissionEditor::_itemCommandChanged); - connect(item, &MissionItem::coordinateChanged, this, &MissionEditor::_itemCoordinateChanged); + connect(item, &MissionItem::commandChanged, this, &MissionEditorController::_itemCommandChanged); + connect(item, &MissionItem::coordinateChanged, this, &MissionEditorController::_itemCoordinateChanged); } -void MissionEditor::_deinitMissionItem(MissionItem* item) +void MissionEditorController::_deinitMissionItem(MissionItem* item) { - disconnect(item, &MissionItem::commandChanged, this, &MissionEditor::_itemCommandChanged); - disconnect(item, &MissionItem::coordinateChanged, this, &MissionEditor::_itemCoordinateChanged); + disconnect(item, &MissionItem::commandChanged, this, &MissionEditorController::_itemCommandChanged); + disconnect(item, &MissionItem::coordinateChanged, this, &MissionEditorController::_itemCoordinateChanged); } -void MissionEditor::_itemCoordinateChanged(const QGeoCoordinate& coordinate) +void MissionEditorController::_itemCoordinateChanged(const QGeoCoordinate& coordinate) { Q_UNUSED(coordinate); _recalcWaypointLines(); } -void MissionEditor::_itemCommandChanged(MavlinkQmlSingleton::Qml_MAV_CMD command) +void MissionEditorController::_itemCommandChanged(MavlinkQmlSingleton::Qml_MAV_CMD command) { Q_UNUSED(command);; _recalcChildItems(); _recalcWaypointLines(); } -void MissionEditor::_activeVehicleChanged(Vehicle* activeVehicle) +void MissionEditorController::_activeVehicleChanged(Vehicle* activeVehicle) { if (_activeVehicle) { - disconnect(_activeVehicle, &Vehicle::homePositionAvailableChanged, this, &MissionEditor::_activeVehicleHomePositionAvailableChanged); - disconnect(_activeVehicle, &Vehicle::homePositionChanged, this, &MissionEditor::_activeVehicleHomePositionChanged); + disconnect(_activeVehicle, &Vehicle::homePositionAvailableChanged, this, &MissionEditorController::_activeVehicleHomePositionAvailableChanged); + disconnect(_activeVehicle, &Vehicle::homePositionChanged, this, &MissionEditorController::_activeVehicleHomePositionChanged); _activeVehicle = NULL; _activeVehicleHomePositionAvailableChanged(false); } @@ -363,20 +353,20 @@ void MissionEditor::_activeVehicleChanged(Vehicle* activeVehicle) _activeVehicle = activeVehicle; if (_activeVehicle) { - connect(_activeVehicle, &Vehicle::homePositionAvailableChanged, this, &MissionEditor::_activeVehicleHomePositionAvailableChanged); - connect(_activeVehicle, &Vehicle::homePositionChanged, this, &MissionEditor::_activeVehicleHomePositionChanged); + connect(_activeVehicle, &Vehicle::homePositionAvailableChanged, this, &MissionEditorController::_activeVehicleHomePositionAvailableChanged); + connect(_activeVehicle, &Vehicle::homePositionChanged, this, &MissionEditorController::_activeVehicleHomePositionChanged); _activeVehicleHomePositionChanged(_activeVehicle->homePosition()); _activeVehicleHomePositionAvailableChanged(_activeVehicle->homePositionAvailable()); } } -void MissionEditor::_activeVehicleHomePositionAvailableChanged(bool homePositionAvailable) +void MissionEditorController::_activeVehicleHomePositionAvailableChanged(bool homePositionAvailable) { _liveHomePositionAvailable = homePositionAvailable; emit liveHomePositionAvailableChanged(_liveHomePositionAvailable); } -void MissionEditor::_activeVehicleHomePositionChanged(const QGeoCoordinate& homePosition) +void MissionEditorController::_activeVehicleHomePositionChanged(const QGeoCoordinate& homePosition) { _liveHomePosition = homePosition; emit liveHomePositionChanged(_liveHomePosition); diff --git a/src/MissionEditor/MissionEditor.h b/src/MissionEditor/MissionEditorController.h similarity index 94% rename from src/MissionEditor/MissionEditor.h rename to src/MissionEditor/MissionEditorController.h index c195cbe91..c83304510 100644 --- a/src/MissionEditor/MissionEditor.h +++ b/src/MissionEditor/MissionEditorController.h @@ -21,20 +21,21 @@ This file is part of the QGROUNDCONTROL project ======================================================================*/ -#ifndef MissionEditor_H -#define MissionEditor_H +#ifndef MissionEditorController_H +#define MissionEditorController_H + +#include -#include "QGCQmlWidgetHolder.h" #include "QmlObjectListModel.h" #include "Vehicle.h" -class MissionEditor : public QGCQmlWidgetHolder +class MissionEditorController : public QObject { Q_OBJECT public: - MissionEditor(QWidget* parent = NULL); - ~MissionEditor(); + MissionEditorController(QWidget* parent = NULL); + ~MissionEditorController(); Q_PROPERTY(QmlObjectListModel* missionItems READ missionItems NOTIFY missionItemsChanged) Q_PROPERTY(QmlObjectListModel* waypointLines READ waypointLines NOTIFY waypointLinesChanged) diff --git a/src/QGCApplication.cc b/src/QGCApplication.cc index 84cdab1ca..b94f00a68 100644 --- a/src/QGCApplication.cc +++ b/src/QGCApplication.cc @@ -85,6 +85,11 @@ #include "FlightMapSettings.h" #include "QGCQGeoCoordinate.h" #include "CoordinateVector.h" +#include "MainToolBarController.h" +#include "MissionEditorController.h" +#include "FlightDisplayViewController.h" +#include "VideoSurface.h" +#include "VideoReceiver.h" #ifndef __ios__ #include "SerialLink.h" @@ -333,7 +338,9 @@ void QGCApplication::_initCommon(void) qmlRegisterUncreatableType ("QGroundControl", 1, 0, "QmlObjectListModel", "Reference only"); qmlRegisterUncreatableType ("QGroundControl", 1, 0, "QGCQGeoCoordinate", "Reference only"); qmlRegisterUncreatableType ("QGroundControl", 1, 0, "CoordinateVector", "Reference only"); - + qmlRegisterUncreatableType ("QGroundControl", 1, 0, "VideoSurface", "Reference only"); + qmlRegisterUncreatableType ("QGroundControl", 1, 0, "VideoReceiver", "Reference only"); + qmlRegisterType ("QGroundControl.Controllers", 1, 0, "ParameterEditorController"); qmlRegisterType ("QGroundControl.Controllers", 1, 0, "FlightModesComponentController"); qmlRegisterType ("QGroundControl.Controllers", 1, 0, "AirframeComponentController"); @@ -341,7 +348,10 @@ void QGCApplication::_initCommon(void) qmlRegisterType ("QGroundControl.Controllers", 1, 0, "PowerComponentController"); qmlRegisterType ("QGroundControl.Controllers", 1, 0, "RadioComponentController"); qmlRegisterType ("QGroundControl.Controllers", 1, 0, "ScreenToolsController"); - + qmlRegisterType ("QGroundControl.Controllers", 1, 0, "MainToolBarController"); + qmlRegisterType ("QGroundControl.Controllers", 1, 0, "MissionEditorController"); + qmlRegisterType ("QGroundControl.Controllers", 1, 0, "FlightDisplayViewController"); + #ifndef __mobile__ qmlRegisterType ("QGroundControl.Controllers", 1, 0, "ViewWidgetController"); qmlRegisterType ("QGroundControl.Controllers", 1, 0, "CustomCommandWidgetController"); @@ -636,8 +646,9 @@ void QGCApplication::_createSingletons(void) void QGCApplication::_destroySingletons(void) { - if (MainWindow::instance()) { - delete MainWindow::instance(); + MainWindow* mainWindow = MainWindow::instance(); + if (mainWindow) { + delete mainWindow; } if (LinkManager::instance(true /* nullOk */)) { @@ -804,7 +815,7 @@ void QGCApplication::showToolBarMessage(const QString& message) { MainWindow* mainWindow = MainWindow::instance(); if (mainWindow) { - mainWindow->getMainToolBar()->showToolBarMessage(message); + mainWindow->showToolbarMessage(message); } else { QGCMessageBox::information("", message); } diff --git a/src/QGCFileDialog.cc b/src/QGCFileDialog.cc index ca28c1ef3..74fdfb3fc 100644 --- a/src/QGCFileDialog.cc +++ b/src/QGCFileDialog.cc @@ -24,6 +24,7 @@ #include "QGCFileDialog.h" #include "QGCApplication.h" #include "MainWindow.h" + #ifdef QT_DEBUG #ifndef __mobile__ #include "UnitTest.h" diff --git a/src/QGCMessageBox.h b/src/QGCMessageBox.h index 4818253b1..646fdc854 100644 --- a/src/QGCMessageBox.h +++ b/src/QGCMessageBox.h @@ -28,10 +28,12 @@ #include "MainWindow.h" #include "QGCApplication.h" + #ifdef QT_DEBUG #ifndef __mobile__ #include "UnitTest.h" #endif + #endif /// @file diff --git a/src/QGCQmlWidgetHolder.cpp b/src/QGCQmlWidgetHolder.cpp index ca44aea1a..07a383f7c 100644 --- a/src/QGCQmlWidgetHolder.cpp +++ b/src/QGCQmlWidgetHolder.cpp @@ -31,6 +31,8 @@ QGCQmlWidgetHolder::QGCQmlWidgetHolder(const QString& title, QAction* action, QW { _ui.setupUi(this); + layout()->setContentsMargins(0,0,0,0); + if (action) { setWindowTitle(title); } @@ -70,4 +72,4 @@ QQuickItem* QGCQmlWidgetHolder::getRootObject(void) void QGCQmlWidgetHolder::setResizeMode(QQuickWidget::ResizeMode resizeMode) { _ui.qmlWidget->setResizeMode(resizeMode); -} \ No newline at end of file +} diff --git a/src/QmlControls/QGroundControl.Controls.qmldir b/src/QmlControls/QGroundControl.Controls.qmldir index a1d409f2b..cd0edaadb 100644 --- a/src/QmlControls/QGroundControl.Controls.qmldir +++ b/src/QmlControls/QGroundControl.Controls.qmldir @@ -34,3 +34,6 @@ MissionItemIndexLabel 1.0 MissionItemIndexLabel.qml MissionItemSummary 1.0 MissionItemSummary.qml MissionItemEditor 1.0 MissionItemEditor.qml +MainToolBar 1.0 MainToolBar.qml +FlightDisplayView 1.0 FlightDisplayView.qml + diff --git a/src/VehicleSetup/SetupView.cc b/src/VehicleSetup/SetupView.cc deleted file mode 100644 index 90e63b161..000000000 --- a/src/VehicleSetup/SetupView.cc +++ /dev/null @@ -1,97 +0,0 @@ -/*===================================================================== - - QGroundControl Open Source Ground Control Station - - (c) 2009 - 2015 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 "SetupView.h" - -#include "AutoPilotPluginManager.h" -#include "VehicleComponent.h" -#include "QGCQmlWidgetHolder.h" -#include "MainWindow.h" -#include "QGCMessageBox.h" -#ifndef __mobile__ -#include "FirmwareUpgradeController.h" -#endif -#include "ParameterEditorController.h" - -#include -#include -#include - -SetupView::SetupView(QWidget* parent) : - QGCQmlWidgetHolder(QString(), NULL, parent) -{ - setSource(QUrl::fromUserInput("qrc:/qml/SetupView.qml")); -} - -SetupView::~SetupView() -{ - -} - -#ifdef UNITTEST_BUILD -void SetupView::showFirmware(void) -{ -#ifndef __mobile__ - QVariant returnedValue; - bool success = QMetaObject::invokeMethod(getRootObject(), - "showFirmwarePanel", - Q_RETURN_ARG(QVariant, returnedValue)); - Q_ASSERT(success); - Q_UNUSED(success); -#endif -} - -void SetupView::showParameters(void) -{ - QVariant returnedValue; - bool success = QMetaObject::invokeMethod(getRootObject(), - "showParametersPanel", - Q_RETURN_ARG(QVariant, returnedValue)); - Q_ASSERT(success); - Q_UNUSED(success); -} - -void SetupView::showSummary(void) -{ - QVariant returnedValue; - bool success = QMetaObject::invokeMethod(getRootObject(), - "showSummaryPanel", - Q_RETURN_ARG(QVariant, returnedValue)); - Q_ASSERT(success); - Q_UNUSED(success); -} - -void SetupView::showVehicleComponentSetup(VehicleComponent* vehicleComponent) -{ - QVariant returnedValue; - bool success = QMetaObject::invokeMethod(getRootObject(), - "showVehicleComponentPanel", - Q_RETURN_ARG(QVariant, returnedValue), - Q_ARG(QVariant, QVariant::fromValue((VehicleComponent*)vehicleComponent))); - Q_ASSERT(success); - Q_UNUSED(success); -} -#endif diff --git a/src/VehicleSetup/SetupView.h b/src/VehicleSetup/SetupView.h deleted file mode 100644 index 85b06c12e..000000000 --- a/src/VehicleSetup/SetupView.h +++ /dev/null @@ -1,54 +0,0 @@ -/*===================================================================== - - 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 SETUPVIEW_H -#define SETUPVIEW_H - -#include "UASInterface.h" -#include "VehicleComponent.h" -#include "AutoPilotPlugin.h" -#include "QGCQmlWidgetHolder.h" - -#include - -/// @file -/// @brief This class is used to display the UI for the VehicleComponent objects. -/// @author Don Gagne - -class SetupView : public QGCQmlWidgetHolder -{ - Q_OBJECT - -public: - explicit SetupView(QWidget* parent = 0); - ~SetupView(); - -#ifdef UNITTEST_BUILD - void showFirmware(void); - void showParameters(void); - void showSummary(void); - void showVehicleComponentSetup(VehicleComponent* vehicleComponent); -#endif -}; - -#endif diff --git a/src/VehicleSetup/SetupView.qml b/src/VehicleSetup/SetupView.qml index d75ac2d57..09ab45f64 100644 --- a/src/VehicleSetup/SetupView.qml +++ b/src/VehicleSetup/SetupView.qml @@ -37,6 +37,7 @@ import QGroundControl.MultiVehicleManager 1.0 Rectangle { id: topLevel color: palette.window + z: zOrder // zOrder comes from the Loader in MainWindow.qml QGCPalette { id: palette; colorGroupEnabled: true } diff --git a/src/VehicleSetup/SetupViewTest.cc b/src/VehicleSetup/SetupViewTest.cc index a9b58f8a2..afa80a0fb 100644 --- a/src/VehicleSetup/SetupViewTest.cc +++ b/src/VehicleSetup/SetupViewTest.cc @@ -27,14 +27,12 @@ #include "SetupViewTest.h" #include "MockLink.h" #include "QGCMessageBox.h" -#include "SetupView.h" #include "MultiVehicleManager.h" UT_REGISTER_TEST(SetupViewTest) SetupViewTest::SetupViewTest(void) : - _mainWindow(NULL), - _mainToolBar(NULL) + _mainWindow(NULL) { } @@ -45,9 +43,6 @@ void SetupViewTest::init(void) _mainWindow = MainWindow::_create(NULL); Q_CHECK_PTR(_mainWindow); - - _mainToolBar = _mainWindow->getMainToolBar(); - Q_ASSERT(_mainToolBar); } void SetupViewTest::cleanup(void) @@ -78,33 +73,29 @@ void SetupViewTest::_clickThrough_test(void) AutoPilotPlugin* autopilot = MultiVehicleManager::instance()->activeVehicle()->autopilotPlugin(); Q_ASSERT(autopilot); - // Switch to the Setup view - _mainToolBar->onSetupView(); - QTest::qWait(1000); - MainWindow* mainWindow = MainWindow::instance(); Q_ASSERT(mainWindow); - QWidget* setupViewWidget = mainWindow->getCurrentViewWidget(); - Q_ASSERT(setupViewWidget); - SetupView* setupView = qobject_cast(setupViewWidget); - Q_ASSERT(setupView); + // Switch to the Setup view + _mainWindow->showSetupView(); + QTest::qWait(1000); + // Click through fixed buttons qDebug() << "Showing firmware"; - setupView->showFirmware(); + _mainWindow->showSetupFirmware(); QTest::qWait(1000); qDebug() << "Showing parameters"; - setupView->showParameters(); + _mainWindow->showSetupParameters(); QTest::qWait(1000); qDebug() << "Showing summary"; - setupView->showSummary(); + _mainWindow->showSetupSummary(); QTest::qWait(1000); const QVariantList& components = autopilot->vehicleComponents(); foreach(QVariant varComponent, components) { VehicleComponent* component = qobject_cast(qvariant_cast(varComponent)); qDebug() << "Showing" << component->name(); - setupView->showVehicleComponentSetup(component); + _mainWindow->showSetupVehicleComponent(component); QTest::qWait(1000); } diff --git a/src/VehicleSetup/SetupViewTest.h b/src/VehicleSetup/SetupViewTest.h index 08681498e..134fc212d 100644 --- a/src/VehicleSetup/SetupViewTest.h +++ b/src/VehicleSetup/SetupViewTest.h @@ -29,7 +29,6 @@ #include "UnitTest.h" #include "MainWindow.h" -#include "MainToolBar.h" /// Click through test for Setup View buttons class SetupViewTest : public UnitTest @@ -47,7 +46,6 @@ private slots: private: MainWindow* _mainWindow; - MainToolBar* _mainToolBar; }; #endif diff --git a/src/qgcunittest/MainWindowTest.cc b/src/qgcunittest/MainWindowTest.cc index 94ce67ce1..b9681d31a 100644 --- a/src/qgcunittest/MainWindowTest.cc +++ b/src/qgcunittest/MainWindowTest.cc @@ -34,8 +34,7 @@ UT_REGISTER_TEST(MainWindowTest) MainWindowTest::MainWindowTest(void) : - _mainWindow(NULL), - _mainToolBar(NULL) + _mainWindow(NULL) { } @@ -46,14 +45,12 @@ void MainWindowTest::init(void) _mainWindow = MainWindow::_create(NULL); Q_CHECK_PTR(_mainWindow); - - _mainToolBar = _mainWindow->getMainToolBar(); - Q_ASSERT(_mainToolBar); } void MainWindowTest::cleanup(void) { _mainWindow->close(); + QTest::qWait(200); delete _mainWindow; UnitTest::cleanup(); @@ -78,11 +75,11 @@ void MainWindowTest::_connectWindowClose_test(MAV_AUTOPILOT autopilot) // Cycle through all the top level views - _mainToolBar->onSetupView(); + _mainWindow->showSetupView(); QTest::qWait(200); - _mainToolBar->onPlanView(); + _mainWindow->showPlanView(); QTest::qWait(200); - _mainToolBar->onFlyView(); + _mainWindow->showFlyView(); QTest::qWait(200); // On MainWindow close we should get a message box telling the user to disconnect first. Cancel should do nothing. diff --git a/src/qgcunittest/MainWindowTest.h b/src/qgcunittest/MainWindowTest.h index 488b435b6..39e9955d2 100644 --- a/src/qgcunittest/MainWindowTest.h +++ b/src/qgcunittest/MainWindowTest.h @@ -31,7 +31,6 @@ #include "UnitTest.h" #include "MainWindow.h" -#include "MainToolBar.h" class MainWindowTest : public UnitTest { @@ -51,7 +50,6 @@ private: void _connectWindowClose_test(MAV_AUTOPILOT autopilot); MainWindow* _mainWindow; - MainToolBar* _mainToolBar; }; #endif diff --git a/src/ui/MainWindow.cc b/src/ui/MainWindow.cc index 04e8938ea..ee9307cce 100644 --- a/src/ui/MainWindow.cc +++ b/src/ui/MainWindow.cc @@ -38,6 +38,7 @@ This file is part of the QGROUNDCONTROL project #include #include #include +#include #include "QGC.h" #include "MAVLinkProtocol.h" @@ -46,14 +47,11 @@ This file is part of the QGROUNDCONTROL project #include "QGCMAVLinkLogPlayer.h" #include "SettingsDialog.h" #include "MAVLinkDecoder.h" -#include "FlightDisplayView.h" -#include "SetupView.h" #include "QGCApplication.h" #include "QGCFileDialog.h" #include "QGCMessageBox.h" #include "MultiVehicleManager.h" #include "HomePositionManager.h" -#include "MissionEditor.h" #include "LogCompressor.h" #include "UAS.h" @@ -128,11 +126,8 @@ MainWindow::MainWindow(QSplashScreen* splashScreen) : _autoReconnect(false) , _lowPowerMode(false) , _showStatusBar(false) - , _centerStackActionGroup(new QActionGroup(this)) - , _centralLayout(NULL) - , _currentViewWidget(NULL) , _splashScreen(splashScreen) - , _currentView(VIEW_SETUP) + , _mainQmlWidgetHolder(NULL) { Q_ASSERT(_instance == NULL); _instance = this; @@ -148,6 +143,7 @@ MainWindow::MainWindow(QSplashScreen* splashScreen) // Setup user interface loadSettings(); emit initStatusChanged(tr("Setting up user interface"), Qt::AlignLeft | Qt::AlignBottom, QColor(62, 93, 141)); + _ui.setupUi(this); // Make sure tool bar elements all fit before changing minimum width setMinimumWidth(1008); @@ -155,10 +151,18 @@ MainWindow::MainWindow(QSplashScreen* splashScreen) // Setup central widget with a layout to hold the views _centralLayout = new QVBoxLayout(); - _centralLayout->setContentsMargins(0,0,0,0); + _centralLayout->setContentsMargins(0, 0, 0, 0); centralWidget()->setLayout(_centralLayout); + + _mainQmlWidgetHolder = new QGCQmlWidgetHolder(QString(), NULL, this); + _centralLayout->addWidget(_mainQmlWidgetHolder); + _mainQmlWidgetHolder->setVisible(true); + + _mainQmlWidgetHolder->setContextPropertyObject("controller", this); + _mainQmlWidgetHolder->setSource(QUrl::fromUserInput("qrc:qml/MainWindow.qml")); + // Set dock options - setDockOptions(AnimatedDocks | AllowTabbedDocks | AllowNestedDocks); + setDockOptions(0); // Setup corners setCorner(Qt::BottomRightCorner, Qt::BottomDockWidgetArea); @@ -167,26 +171,12 @@ MainWindow::MainWindow(QSplashScreen* splashScreen) menuBar()->setNativeMenuBar(false); #endif -#ifndef __mobile__ #ifdef UNITTEST_BUILD QAction* qmlTestAction = new QAction("Test QML palette and controls", NULL); connect(qmlTestAction, &QAction::triggered, this, &MainWindow::_showQmlTestWidget); _ui.menuWidgets->addAction(qmlTestAction); -#endif #endif - // Load QML Toolbar - QDockWidget* widget = new QDockWidget(this); - widget->setObjectName("ToolBarDockWidget"); - qmlRegisterType("QGroundControl.MainToolBar", 1, 0, "MainToolBar"); - _mainToolBar = new MainToolBar(widget); - widget->setWidget(_mainToolBar); - widget->setFeatures(QDockWidget::NoDockWidgetFeatures); - widget->setTitleBarWidget(new QWidget(this)); // Disables the title bar - addDockWidget(Qt::TopDockWidgetArea, widget); - - // Setup UI state machines - _centerStackActionGroup->setExclusive(true); // Status Bar setStatusBar(new QStatusBar(this)); statusBar()->setSizeGripEnabled(true); @@ -226,8 +216,7 @@ MainWindow::MainWindow(QSplashScreen* splashScreen) // Set low power mode enableLowPowerMode(_lowPowerMode); emit initStatusChanged(tr("Restoring last view state"), Qt::AlignLeft | Qt::AlignBottom, QColor(62, 93, 141)); - // Restore the window setup - _loadCurrentViewState(); + #ifndef __mobile__ // Restore the window position and size @@ -286,6 +275,8 @@ MainWindow::MainWindow(QSplashScreen* splashScreen) _ui.actionFullscreen->setShortcut(QApplication::translate("MainWindow", "Ctrl+Return", 0)); #endif + _ui.actionFlight->setChecked(true); + connect(&windowNameUpdateTimer, SIGNAL(timeout()), this, SLOT(configureWindowName())); windowNameUpdateTimer.start(15000); emit initStatusChanged(tr("Done"), Qt::AlignLeft | Qt::AlignBottom, QColor(62, 93, 141)); @@ -321,24 +312,9 @@ MainWindow::MainWindow(QSplashScreen* splashScreen) MainWindow::~MainWindow() { - // Delete all UAS objects - for (int i=0;i<_commsWidgetList.size();i++) - { - _commsWidgetList[i]->deleteLater(); - } _instance = NULL; } -void MainWindow::resizeEvent(QResizeEvent * event) -{ - QMainWindow::resizeEvent(event); -} - -QString MainWindow::_getWindowStateKey() -{ - return QString::number(_currentView)+"_windowstate_"; -} - QString MainWindow::_getWindowGeometryKey() { return "_geometry"; @@ -447,30 +423,6 @@ void MainWindow::_showDockWidgetAction(bool show) } #endif -void MainWindow::_buildMissionEditorView(void) -{ - if (!_missionEditorView) { - _missionEditorView = new MissionEditor(this); - _missionEditorView->setVisible(false); - } -} - -void MainWindow::_buildFlightView(void) -{ - if (!_flightView) { - _flightView = new FlightDisplayView(this); - _flightView->setVisible(false); - } -} - -void MainWindow::_buildSetupView(void) -{ - if (!_setupView) { - _setupView = new SetupView(this); - _setupView->setVisible(false); - } -} - void MainWindow::fullScreenActionItemCallback(bool) { _ui.actionNormal->setChecked(false); @@ -514,7 +466,14 @@ void MainWindow::closeEvent(QCloseEvent *event) // Should not be any active connections Q_ASSERT(!LinkManager::instance()->anyConnectedLinks()); - + + // We have to pull out the QmlWidget from the main window and delete it here, before + // the MainWindow ends up getting deleted. Otherwise the Qml has a reference to MainWindow + // inside it which in turn causes a shutdown crash. + _centralLayout->removeWidget(_mainQmlWidgetHolder); + delete _mainQmlWidgetHolder; + _mainQmlWidgetHolder = NULL; + _storeCurrentViewState(); storeSettings(); event->accept(); @@ -540,10 +499,6 @@ void MainWindow::storeSettings() settings.setValue("SHOW_STATUSBAR", _showStatusBar); settings.endGroup(); settings.setValue(_getWindowGeometryKey(), saveGeometry()); - - // Save the last current view in any case - settings.setValue("CURRENT_VIEW", _currentView); - settings.setValue(_getWindowStateKey(), saveState()); #ifndef __mobile__ _storeVisibleWidgetsSettings(); @@ -581,43 +536,9 @@ void MainWindow::enableAutoReconnect(bool enabled) **/ void MainWindow::connectCommonActions() { - // Bind together the perspective actions - QActionGroup* perspectives = new QActionGroup(_ui.menuPerspectives); - perspectives->addAction(_ui.actionPlan); - perspectives->addAction(_ui.actionSetup); - perspectives->setExclusive(true); - - if (_currentView == VIEW_FLIGHT) - { - _ui.actionFlight->setChecked(true); - _ui.actionFlight->activate(QAction::Trigger); - } - if (_currentView == VIEW_MISSIONEDITOR) - { - _ui.actionPlan->setChecked(true); - _ui.actionPlan->activate(QAction::Trigger); - } - if (_currentView == VIEW_SETUP) - { - _ui.actionSetup->setChecked(true); - _ui.actionSetup->activate(QAction::Trigger); - } - // Connect actions from ui connect(_ui.actionAdd_Link, SIGNAL(triggered()), this, SLOT(manageLinks())); - // Connect internal actions - connect(MultiVehicleManager::instance(), &MultiVehicleManager::vehicleAdded, this, &MainWindow::_vehicleAdded); - - // Views actions - connect(_ui.actionFlight, SIGNAL(triggered()), this, SLOT(loadFlightView())); - connect(_ui.actionPlan, SIGNAL(triggered()), this, SLOT(loadPlanView())); - - // Help Actions - connect(_ui.actionOnline_Documentation, SIGNAL(triggered()), this, SLOT(showHelp())); - connect(_ui.actionDeveloper_Credits, SIGNAL(triggered()), this, SLOT(showCredits())); - connect(_ui.actionProject_Roadmap, SIGNAL(triggered()), this, SLOT(showRoadMap())); - // Audio output _ui.actionMuteAudioOutput->setChecked(GAudioOutput::instance()->isMuted()); connect(GAudioOutput::instance(), SIGNAL(mutedChanged(bool)), _ui.actionMuteAudioOutput, SLOT(setChecked(bool))); @@ -626,8 +547,13 @@ void MainWindow::connectCommonActions() // Application Settings connect(_ui.actionSettings, SIGNAL(triggered()), this, SLOT(showSettings())); - // Update Tool Bar - _mainToolBar->setCurrentView(_currentView); + // Views actions + connect(_ui.actionFlight, &QAction::triggered, this, &MainWindow::showFlyView); + connect(_ui.actionPlan, &QAction::triggered, this, &MainWindow::showPlanView); + connect(_ui.actionSetup, &QAction::triggered, this, &MainWindow::showSetupView); + + // Connect internal actions + connect(MultiVehicleManager::instance(), &MultiVehicleManager::vehicleAdded, this, &MainWindow::_vehicleAdded); } void MainWindow::_openUrl(const QString& url, const QString& errorMessage) @@ -640,43 +566,12 @@ void MainWindow::_openUrl(const QString& url, const QString& errorMessage) } } -void MainWindow::showHelp() -{ - _openUrl( - "http://qgroundcontrol.org/users/start", - tr("To get to the online help, please open http://qgroundcontrol.org/user_guide in a browser.")); -} - -void MainWindow::showCredits() -{ - _openUrl( - "http://qgroundcontrol.org/credits", - tr("To get to the credits, please open http://qgroundcontrol.org/credits in a browser.")); -} - -void MainWindow::showRoadMap() -{ - _openUrl( - "http://qgroundcontrol.org/dev/roadmap", - tr("To get to the online help, please open http://qgroundcontrol.org/roadmap in a browser.")); -} - void MainWindow::showSettings() { SettingsDialog settings(this); settings.exec(); } -void MainWindow::commsWidgetDestroyed(QObject *obj) -{ - // Do not dynamic cast or de-reference QObject, since object is either in destructor or may have already - // been destroyed. - if (_commsWidgetList.contains(obj)) - { - _commsWidgetList.removeOne(obj); - } -} - void MainWindow::_vehicleAdded(Vehicle* vehicle) { connect(vehicle->uas(), SIGNAL(valueChanged(int,QString,QString,QVariant,quint64)), this, SIGNAL(valueChanged(int,QString,QString,QVariant,quint64))); @@ -691,95 +586,9 @@ void MainWindow::_storeCurrentViewState(void) } #endif - settings.setValue(_getWindowStateKey(), saveState()); settings.setValue(_getWindowGeometryKey(), saveGeometry()); } -/// Restores the state of the toolbar, status bar and widgets associated with the current view -void MainWindow::_loadCurrentViewState(void) -{ - QWidget* centerView = NULL; - - switch (_currentView) { - case VIEW_SETUP: - _buildSetupView(); - centerView = _setupView; - break; - - case VIEW_FLIGHT: - _buildFlightView(); - centerView = _flightView; - break; - - case VIEW_MISSIONEDITOR: - _buildMissionEditorView(); - centerView = _missionEditorView; - break; - - default: - Q_ASSERT(false); - break; - } - - // Remove old view - if (_currentViewWidget) { - _currentViewWidget->setVisible(false); - Q_ASSERT(_centralLayout->count() == 1); - QLayoutItem *child = _centralLayout->takeAt(0); - Q_ASSERT(child); - delete child; - } - - // Add the new one - Q_ASSERT(centerView); - Q_ASSERT(_centralLayout->count() == 0); - _currentViewWidget = centerView; - _centralLayout->addWidget(_currentViewWidget); - _centralLayout->setContentsMargins(0, 0, 0, 0); - _currentViewWidget->setVisible(true); - - if (settings.contains(_getWindowStateKey())) { - restoreState(settings.value(_getWindowStateKey()).toByteArray()); - } - - // There is a bug in Qt where a Canvas element inside a QQuickWidget does not - // receive update requests. Here we emit a signal for them to get repainted. - emit repaintCanvas(); -} - -void MainWindow::loadPlanView() -{ - if (_currentView != VIEW_MISSIONEDITOR) - { - _storeCurrentViewState(); - _currentView = VIEW_MISSIONEDITOR; - _ui.actionPlan->setChecked(true); - _loadCurrentViewState(); - } -} - -void MainWindow::loadSetupView() -{ - if (_currentView != VIEW_SETUP) - { - _storeCurrentViewState(); - _currentView = VIEW_SETUP; - _ui.actionSetup->setChecked(true); - _loadCurrentViewState(); - } -} - -void MainWindow::loadFlightView() -{ - if (_currentView != VIEW_FLIGHT) - { - _storeCurrentViewState(); - _currentView = VIEW_FLIGHT; - _ui.actionFlight->setChecked(true); - _loadCurrentViewState(); - } -} - /// @brief Hides the spash screen if it is currently being shown void MainWindow::hideSplashScreen(void) { diff --git a/src/ui/MainWindow.h b/src/ui/MainWindow.h index 9f8182575..838f77c06 100644 --- a/src/ui/MainWindow.h +++ b/src/ui/MainWindow.h @@ -37,25 +37,24 @@ This file is part of the QGROUNDCONTROL project #include #include -#include "ui_MainWindow.h" #include "LinkManager.h" #include "LinkInterface.h" #include "UASInterface.h" #include "CameraView.h" -#include "MainToolBar.h" #include "LogCompressor.h" -#include "FlightDisplayView.h" #include "QGCMAVLinkInspector.h" #include "QGCMAVLinkLogPlayer.h" #include "MAVLinkDecoder.h" #include "Vehicle.h" #include "QGCDockWidget.h" +#include "QGCQmlWidgetHolder.h" + +#include "ui_MainWindow.h" #if (defined QGC_MOUSE_ENABLED_WIN) | (defined QGC_MOUSE_ENABLED_LINUX) #include "Mouse6dofInput.h" #endif // QGC_MOUSE_ENABLED_WIN - class QSplashScreen; class QGCStatusBar; class Linecharts; @@ -67,7 +66,6 @@ class QGCDataPlot2D; **/ class MainWindow : public QMainWindow { - friend class MainToolBar; Q_OBJECT public: @@ -106,32 +104,13 @@ public: /// @brief Restore (and connects) the last used connection (if any) void restoreLastUsedConnection(); - - /// @brief Gets a pointer to the Main Tool Bar - MainToolBar* getMainToolBar(void) { return _mainToolBar; } - - /// @brief Gets a pointer to the Main Flight Display - FlightDisplayView* getFlightDisplay() { return dynamic_cast(_flightView.data()); } - - QWidget* getCurrentViewWidget(void) { return _currentViewWidget; } public slots: /** @brief Show the application settings */ void showSettings(); - void loadSetupView(); - void loadFlightView(); - void loadPlanView(); - void manageLinks(); - /** @brief Show the online help for users */ - void showHelp(); - /** @brief Show the authors / credits */ - void showCredits(); - /** @brief Show the project roadmap */ - void showRoadMap(); - /** @brief Automatically reconnect last link */ void enableAutoReconnect(bool enabled); @@ -143,8 +122,6 @@ public slots: /** @brief Update the window name */ void configureWindowName(); - void commsWidgetDestroyed(QObject *obj); - protected slots: /** * @brief Unchecks the normalActionItem. @@ -164,6 +141,19 @@ protected slots: void showStatusBarCallback(bool checked); signals: + // Signals the Qml to show the specified view + void showFlyView(void); + void showPlanView(void); + void showSetupView(void); + + void showToolbarMessage(const QString& message); + + // These are used for unit testing + void showSetupFirmware(void); + void showSetupParameters(void); + void showSetupSummary(void); + void showSetupVehicleComponent(VehicleComponent* vehicleComponent); + void initStatusChanged(const QString& message, int alignment, const QColor &color); /** Emitted when any value changes from any source */ void valueChanged(const int uasId, const QString& name, const QString& unit, const QVariant& value, const quint64 msec); @@ -182,22 +172,6 @@ public: } protected: - - typedef enum _VIEW_SECTIONS - { - VIEW_UNUSED5, // Unused (don't remove, or it will screw up saved settigns indices) - VIEW_UNUSED3, // Unused (don't remove, or it will screw up saved settigns indices) - VIEW_FLIGHT, // Flight/Fly/Operate view mode. Used for 1st-person observation of the vehicle. - VIEW_UNUSED4, // Unused (don't remove, or it will screw up saved settigns indices) - VIEW_SETUP, // Setup view. Used for initializing the system for operation. - VIEW_UNUSED1, // Unused (don't remove, or it will screw up saved settigns indices) - VIEW_UNUSED2, // Unused (don't remove, or it will screw up saved settigns indices) - VIEW_MISSIONEDITOR, // New mission editor - } VIEW_SECTIONS; - - /** @brief Catch window resize events */ - void resizeEvent(QResizeEvent * event); - void connectCommonActions(); void loadSettings(); @@ -205,10 +179,6 @@ protected: QSettings settings; - // Center widgets - QPointer linechartWidget; - - QPointer _mainToolBar; QPointer mavlinkDecoder; QGCMAVLinkLogPlayer* logPlayer; @@ -241,7 +211,7 @@ private slots: void _linkStateChange(LinkInterface*); void _closeWindow(void) { close(); } void _vehicleAdded(Vehicle* vehicle); - + #ifndef __mobile__ void _showDockWidgetAction(bool show); #endif @@ -277,12 +247,6 @@ private: QMap _mapName2Action; #endif - void _buildPlanView(void); - void _buildFlightView(void); - void _buildSetupView(void); - void _buildTerminalView(void); - void _buildMissionEditorView(void); - void _storeCurrentViewState(void); void _loadCurrentViewState(void); @@ -300,16 +264,12 @@ private: bool _autoReconnect; bool _lowPowerMode; ///< If enabled, QGC reduces the update rates of all widgets bool _showStatusBar; - QActionGroup* _centerStackActionGroup; QVBoxLayout* _centralLayout; - QList _commsWidgetList; - QWidget* _currentViewWidget; ///< Currently displayed view widget QSplashScreen* _splashScreen; ///< Splash screen, NULL is splash screen not currently being shown - VIEW_SECTIONS _currentView; ///< Currently displayed view Ui::MainWindow _ui; - QString _screenFileName; - QString _getWindowStateKey(); + QGCQmlWidgetHolder* _mainQmlWidgetHolder; + QString _getWindowGeometryKey(); }; diff --git a/src/ui/MainWindow.qml b/src/ui/MainWindow.qml new file mode 100644 index 000000000..0fe81f924 --- /dev/null +++ b/src/ui/MainWindow.qml @@ -0,0 +1,106 @@ +/*===================================================================== + +QGroundControl Open Source Ground Control Station + +(c) 2009, 2015 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 . + +======================================================================*/ + +import QtQuick 2.3 +import QtQuick.Controls 1.2 +import QtPositioning 5.2 + +import QGroundControl.Controls 1.0 +import QGroundControl.FlightMap 1.0 +import QGroundControl.ScreenTools 1.0 + +/// Qml for MainWindow +FlightDisplayView { + id: _root + // sets the top margin soo map widgets are not under toolbar + topMargin: toolbar.height + ScreenTools.defaultFontPixelWidth + + readonly property string _planViewSource: "MissionEditor.qml" + readonly property string _setupViewSource: "SetupView.qml" + + Connections { + target: controller + + onShowFlyView: { + setupViewLoader.visible = false + planViewLoader.visible = false + _root.hideWidgets = false + } + + onShowPlanView: { + if (planViewLoader.source != _planViewSource) { + planViewLoader.source = _planViewSource + } + setupViewLoader.visible = false + planViewLoader.visible = true + _root.hideWidgets = true + } + + onShowSetupView: { + if (setupViewLoader.source != _setupViewSource) { + setupViewLoader.source = _setupViewSource + } + setupViewLoader.visible = true + planViewLoader.visible = false + _root.hideWidgets = true + } + + onShowToolbarMessage: toolbar.showToolbarMessage(message) + + // The following are use for unit testing only + + onShowSetupFirmware: setupViewLoader.item.showFirmwarePanel() + onShowSetupParameters: setupViewLoader.item.showParametersPanel() + onShowSetupSummary: setupViewLoader.item.showSummaryPanel() + onShowSetupVehicleComponent: setupViewLoader.item.showVehicleComponentPanel(vechicleComponent) + } + + MainToolBar { + id: toolbar + width: parent.width + z: _root.zOrderTopMost + } + + Loader { + id: planViewLoader + anchors.left: parent.left + anchors.right: parent.right + anchors.top: toolbar.bottom + anchors.bottom: parent.bottom + visible: false + + property real zOrder: _root.zOrderTopMost + } + + Loader { + id: setupViewLoader + anchors.margins: ScreenTools.defaultFontPixelWidth + anchors.left: parent.left + anchors.right: parent.right + anchors.top: toolbar.bottom + anchors.bottom: parent.bottom + visible: false + + property real zOrder: _root.zOrderTopMost + } +} diff --git a/src/ui/QGCHilFlightGearConfiguration.cc b/src/ui/QGCHilFlightGearConfiguration.cc index 60b04b8af..33004797d 100644 --- a/src/ui/QGCHilFlightGearConfiguration.cc +++ b/src/ui/QGCHilFlightGearConfiguration.cc @@ -1,7 +1,8 @@ #include "QGCHilFlightGearConfiguration.h" - #include "MainWindow.h" +#include + // Various settings groups and keys const char* QGCHilFlightGearConfiguration::_settingsGroup = "QGC_HILCONFIG_FLIGHTGEAR"; const char* QGCHilFlightGearConfiguration::_mavSettingsSubGroupFixedWing = "FIXED_WING"; diff --git a/src/ui/SettingsDialog.cc b/src/ui/SettingsDialog.cc index ea9862b5f..46c53c153 100644 --- a/src/ui/SettingsDialog.cc +++ b/src/ui/SettingsDialog.cc @@ -36,7 +36,7 @@ #include "QGCApplication.h" #include "QGCFileDialog.h" #include "QGCMessageBox.h" -#include "MainToolBar.h" +#include "MainToolBarController.h" #include "FlightMapSettings.h" SettingsDialog::SettingsDialog(QWidget *parent, int showTab, Qt::WindowFlags flags) : @@ -61,15 +61,6 @@ _ui(new Ui::SettingsDialog) this->window()->setWindowTitle(tr("QGroundControl Settings")); - // Tool Bar Preferences - QSettings settings; - settings.beginGroup(TOOL_BAR_SETTINGS_GROUP); - _ui->showBattery->setChecked(settings.value( TOOL_BAR_SHOW_BATTERY, true).toBool()); - _ui->showGPS->setChecked(settings.value( TOOL_BAR_SHOW_GPS, true).toBool()); - _ui->showMav->setChecked(settings.value( TOOL_BAR_SHOW_MAV, true).toBool()); - _ui->showMessages->setChecked(settings.value(TOOL_BAR_SHOW_MESSAGES, true).toBool()); - _ui->showRSSI->setChecked(settings.value( TOOL_BAR_SHOW_RSSI, true).toBool()); - settings.endGroup(); // Audio preferences _ui->audioMuteCheckBox->setChecked(GAudioOutput::instance()->isMuted()); connect(_ui->audioMuteCheckBox, SIGNAL(toggled(bool)), GAudioOutput::instance(), SLOT(mute(bool))); @@ -181,31 +172,6 @@ void SettingsDialog::_selectSavedFilesDirectory(void) // * Parameters } -void SettingsDialog::on_showGPS_clicked(bool checked) -{ - _mainWindow->getMainToolBar()->viewStateChanged(TOOL_BAR_SHOW_GPS, checked); -} - -void SettingsDialog::on_showBattery_clicked(bool checked) -{ - _mainWindow->getMainToolBar()->viewStateChanged(TOOL_BAR_SHOW_BATTERY, checked); -} - -void SettingsDialog::on_showMessages_clicked(bool checked) -{ - _mainWindow->getMainToolBar()->viewStateChanged(TOOL_BAR_SHOW_MESSAGES, checked); -} - -void SettingsDialog::on_showMav_clicked(bool checked) -{ - _mainWindow->getMainToolBar()->viewStateChanged(TOOL_BAR_SHOW_MAV, checked); -} - -void SettingsDialog::on_showRSSI_clicked(bool checked) -{ - _mainWindow->getMainToolBar()->viewStateChanged(TOOL_BAR_SHOW_RSSI, checked); -} - void SettingsDialog::_bingMapRadioClicked(bool checked) { if (checked) { diff --git a/src/ui/SettingsDialog.h b/src/ui/SettingsDialog.h index f991e9b79..d9dc83857 100644 --- a/src/ui/SettingsDialog.h +++ b/src/ui/SettingsDialog.h @@ -55,13 +55,6 @@ private slots: void _deleteSettingsToggled(bool checked); void _selectSavedFilesDirectory(void); void _validateBeforeClose(void); - - void on_showGPS_clicked(bool checked); - void on_showBattery_clicked(bool checked); - void on_showMessages_clicked(bool checked); - void on_showMav_clicked(bool checked); - - void on_showRSSI_clicked(bool checked); void _bingMapRadioClicked(bool checked); void _googleMapRadioClicked(bool checked); diff --git a/src/ui/SettingsDialog.ui b/src/ui/SettingsDialog.ui index 0db0fa3ff..35bd7c871 100644 --- a/src/ui/SettingsDialog.ui +++ b/src/ui/SettingsDialog.ui @@ -281,80 +281,6 @@ - - - - - 0 - 0 - - - - Tool Bar - - - - - - - - - - - 160 - 0 - - - - Show GPS - - - - - - - Show Messages - - - - - - - - - - - - 160 - 0 - - - - Show Battery - - - - - - - Show Mav Icon - - - - - - - - - Show RSSI - - - - - - - - diff --git a/src/ui/toolbar/MainToolBar.qml b/src/ui/toolbar/MainToolBar.qml index 560d3501d..21a95a011 100644 --- a/src/ui/toolbar/MainToolBar.qml +++ b/src/ui/toolbar/MainToolBar.qml @@ -34,12 +34,13 @@ import QtQuick.Controls.Styles 1.2 import QGroundControl.Controls 1.0 import QGroundControl.FactControls 1.0 import QGroundControl.Palette 1.0 -import QGroundControl.MainToolBar 1.0 import QGroundControl.MultiVehicleManager 1.0 import QGroundControl.ScreenTools 1.0 +import QGroundControl.Controllers 1.0 -Rectangle { - id: toolBarHolder +Item { + id: toolBarHolder + height: toolBarHeight property var qgcPal: QGCPalette { id: palette; colorGroupEnabled: true } @@ -63,20 +64,16 @@ Rectangle { property var colorGreenText: (qgcPal.globalTheme === QGCPalette.Light) ? "#046b1b" : "#00d930" property var colorWhiteText: (qgcPal.globalTheme === QGCPalette.Light) ? "#343333" : "#f0f0f0" - color: qgcPal.windowShade + MainToolBarController { id: _controller } - Connections { - target: mainToolBar - - onShowMessage: { - toolBarMessage.text = message - if (toolBarMessage.contentHeight > toolBarMessageCloseButton.height) { - mainToolBar.height = toolBarHeight + toolBarMessage.contentHeight + (verticalMargins * 2) - } else { - mainToolBar.height = toolBarHeight + toolBarMessageCloseButton.height + (verticalMargins * 2) - } - toolBarMessageArea.visible = true + function showToolbarMessage(message) { + toolBarMessage.text = message + if (toolBarMessage.contentHeight > toolBarMessageCloseButton.height) { + mainToolBar.height = toolBarHeight + toolBarMessage.contentHeight + (verticalMargins * 2) + } else { + mainToolBar.height = toolBarHeight + toolBarMessageCloseButton.height + (verticalMargins * 2) } + toolBarMessageArea.visible = true } function getProportionalDimmension(val) { @@ -150,51 +147,50 @@ Rectangle { } function showMavStatus() { - return (multiVehicleManager.activeVehicleAvailable && activeVehicle.heartbeatTimeout === 0 && mainToolBar.connectionCount > 0); + return (multiVehicleManager.activeVehicleAvailable && activeVehicle.heartbeatTimeout === 0 && _controller.connectionCount > 0); } //------------------------------------------------------------------------- //-- Main menu for Mobile Devices Menu { id: maintMenu + ExclusiveGroup { id: mainMenuGroup } + MenuItem { - text: "Vehicle Setup" - checkable: true + id: flyViewShowing + text: "Fly" + checkable: true + checked: true exclusiveGroup: mainMenuGroup - checked: (mainToolBar.currentView === MainToolBar.ViewSetup) - onTriggered: - { - mainToolBar.onSetupView(); + + onTriggered: { + checked = true + _controller.onFlyView(); } } + MenuItem { - text: "Plan View" - checkable: true - checked: (mainToolBar.currentView === MainToolBar.ViewPlan) + id: setupViewShowing + text: "Setup" + checkable: true exclusiveGroup: mainMenuGroup - onTriggered: - { - mainToolBar.onPlanView(); + + onTriggered: { + checked = true + _controller.onSetupView(); } } + MenuItem { - text: "Flight View" - checkable: true - checked: (mainToolBar.currentView === MainToolBar.ViewFly) + id: planViewShowing + text: "Plan" + checkable: true exclusiveGroup: mainMenuGroup - onTriggered: - { - mainToolBar.onFlyView(); - } - } - //-- Flight View Context Menu - MenuItem { - text: "Flight View Options..." - visible: (mainToolBar.currentView === MainToolBar.ViewFly) - onTriggered: - { - mainToolBar.onFlyViewMenu(); + + onTriggered: { + checked = true + _controller.onPlanView(); } } } // Menu @@ -210,7 +206,6 @@ Rectangle { id: messages width: (activeVehicle.messageCount > 99) ? getProportionalDimmension(65) : getProportionalDimmension(60) height: cellHeight - visible: mainToolBar.showMessages anchors.verticalCenter: parent.verticalCenter color: getMessageColor() border.color: "#00000000" @@ -273,7 +268,7 @@ Rectangle { } onClicked: { var p = mapToItem(toolBarHolder, mouseX, mouseY); - mainToolBar.onEnterMessageArea(p.x, p.y); + _controller.onEnterMessageArea(p.x, p.y); } } @@ -282,7 +277,6 @@ Rectangle { QGCButton { width: ScreenTools.defaultFontPixelWidth * 12 height: cellHeight - visible: mainToolBar.showMav anchors.verticalCenter: parent.verticalCenter text: "Vehicle " + activeVehicle.id @@ -336,7 +330,6 @@ Rectangle { id: satelitte width: getProportionalDimmension(55) height: cellHeight - visible: mainToolBar.showGPS anchors.verticalCenter: parent.verticalCenter color: getSatelliteColor(); border.color: "#00000000" @@ -370,9 +363,9 @@ Rectangle { id: rssiRC width: getProportionalDimmension(55) height: cellHeight - visible: mainToolBar.showRSSI && mainToolBar.remoteRSSI <= 100 + visible: _controller.remoteRSSI <= 100 anchors.verticalCenter: parent.verticalCenter - color: getRSSIColor(mainToolBar.remoteRSSI); + color: getRSSIColor(_controller.remoteRSSI); border.color: "#00000000" border.width: 0 Image { @@ -386,7 +379,7 @@ Rectangle { smooth: true } QGCLabel { - text: mainToolBar.remoteRSSI + text: _controller.remoteRSSI anchors.right: parent.right anchors.rightMargin: getProportionalDimmension(6) anchors.verticalCenter: parent.verticalCenter @@ -401,9 +394,9 @@ Rectangle { id: rssiTelemetry width: getProportionalDimmension(80) height: cellHeight - visible: mainToolBar.showRSSI && (mainToolBar.telemetryRRSSI > 0) && (mainToolBar.telemetryLRSSI > 0) + visible: (_controller.telemetryRRSSI > 0) && (_controller.telemetryLRSSI > 0) anchors.verticalCenter: parent.verticalCenter - color: getRSSIColor(Math.min(mainToolBar.telemetryRRSSI,mainToolBar.telemetryLRSSI)); + color: getRSSIColor(Math.min(_controller.telemetryRRSSI,_controller.telemetryLRSSI)); border.color: "#00000000" border.width: 0 Image { @@ -429,7 +422,7 @@ Rectangle { color: colorWhite } QGCLabel { - text: mainToolBar.telemetryRRSSI + 'dB' + text: _controller.telemetryRRSSI + 'dB' width: getProportionalDimmension(30) horizontalAlignment: Text.AlignRight font.pixelSize: ScreenTools.smallFontPixelSize @@ -446,7 +439,7 @@ Rectangle { color: colorWhite } QGCLabel { - text: mainToolBar.telemetryLRSSI + 'dB' + text: _controller.telemetryLRSSI + 'dB' width: getProportionalDimmension(30) horizontalAlignment: Text.AlignRight font.pixelSize: ScreenTools.smallFontPixelSize @@ -461,7 +454,6 @@ Rectangle { id: batteryStatus width: activeVehicle.batteryConsumed < 0.0 ? getProportionalDimmension(60) : getProportionalDimmension(80) height: cellHeight - visible: mainToolBar.showBattery anchors.verticalCenter: parent.verticalCenter color: getBatteryColor(); border.color: "#00000000" @@ -632,40 +624,44 @@ Rectangle { ExclusiveGroup { id: mainActionGroup } QGCToolBarButton { - id: setupButton - width: getProportionalDimmension(90) - height: cellHeight + id: setupButton + width: getProportionalDimmension(90) + height: cellHeight exclusiveGroup: mainActionGroup - text: qsTr("Setup") - checked: (mainToolBar.currentView === MainToolBar.ViewSetup) + text: "Setup" + onClicked: { - mainToolBar.onSetupView(); + checked = true + _controller.onSetupView(); } z: 1000 } QGCToolBarButton { - id: planButton - width: getProportionalDimmension(90) - height: cellHeight + id: planButton + width: getProportionalDimmension(90) + height: cellHeight exclusiveGroup: mainActionGroup - text: qsTr("Plan") - checked: (mainToolBar.currentView === MainToolBar.ViewPlan) + text: "Plan" + onClicked: { - mainToolBar.onPlanView(); + checked = true + _controller.onPlanView(); } z: 900 } QGCToolBarButton { - id: flyButton - width: getProportionalDimmension(90) - height: cellHeight + id: flyButton + width: getProportionalDimmension(90) + height: cellHeight exclusiveGroup: mainActionGroup - text: qsTr("Fly") - checked: (mainToolBar.currentView === MainToolBar.ViewFly) + text: "Fly" + checked: true + onClicked: { - mainToolBar.onFlyView(); + checked = true + _controller.onFlyView(); } z: 800 } @@ -728,7 +724,7 @@ Rectangle { id: connectionStatus width: getProportionalDimmension(160) height: cellHeight - visible: (mainToolBar.connectionCount > 0 && multiVehicleManager.activeVehicleAvailable && activeVehicle.heartbeatTimeout != 0) + visible: (_controller.connectionCount > 0 && multiVehicleManager.activeVehicleAvailable && activeVehicle.heartbeatTimeout != 0) anchors.verticalCenter: parent.verticalCenter color: "#00000000" border.color: "#00000000" @@ -759,7 +755,7 @@ Rectangle { Menu { id: connectMenu Component.onCompleted: { - mainToolBar.configListChanged.connect(connectMenu.updateConnectionList); + _controller.configListChanged.connect(connectMenu.updateConnectionList); connectMenu.updateConnectionList(); } function addMenuEntry(name) { @@ -767,15 +763,15 @@ Rectangle { if(name !== "") label = name; var mItem = connectMenu.addItem(label); - var menuSlot = function() {mainToolBar.onConnect(name)}; + var menuSlot = function() {_controller.onConnect(name)}; mItem.triggered.connect(menuSlot); } function updateConnectionList() { connectMenu.clear(); - for(var i = 0; i < mainToolBar.configList.length; i++) { - connectMenu.addMenuEntry(mainToolBar.configList[i]); + for(var i = 0; i < _controller.configList.length; i++) { + connectMenu.addMenuEntry(_controller.configList[i]); } - if(mainToolBar.configList.length > 0) { + if(_controller.configList.length > 0) { connectMenu.addSeparator(); } // Add "Add Connection" to the list @@ -786,7 +782,7 @@ Rectangle { QGCButton { id: connectButton width: getProportionalDimmension(100) - visible: mainToolBar.connectionCount === 0 + visible: _controller.connectionCount === 0 text: qsTr("Connect") menu: connectMenu } @@ -794,21 +790,21 @@ Rectangle { QGCButton { id: disconnectButton width: getProportionalDimmension(100) - visible: mainToolBar.connectionCount === 1 + visible: _controller.connectionCount === 1 text: qsTr("Disconnect") onClicked: { - mainToolBar.onDisconnect(""); + _controller.onDisconnect(""); } } Menu { id: disconnectMenu Component.onCompleted: { - mainToolBar.connectedListChanged.connect(disconnectMenu.onConnectedListChanged) + _controller.connectedListChanged.connect(disconnectMenu.onConnectedListChanged) } function addMenuEntry(name) { var mItem = disconnectMenu.addItem(name); - var menuSlot = function() {mainToolBar.onDisconnect(name)}; + var menuSlot = function() {_controller.onDisconnect(name)}; mItem.triggered.connect(menuSlot); } function onConnectedListChanged(conList) { @@ -823,7 +819,7 @@ Rectangle { id: multidisconnectButton width: getProportionalDimmension(100) text: "Disconnect" - visible: mainToolBar.connectionCount > 1 + visible: _controller.connectionCount > 1 menu: disconnectMenu } } // Row @@ -833,7 +829,7 @@ Rectangle { id: progressBar anchors.top: toolRow.bottom height: getProportionalDimmension(3) - width: parent.width * mainToolBar.progressBarValue + width: parent.width * _controller.progressBarValue color: qgcPal.text } @@ -868,8 +864,8 @@ Rectangle { onClicked: { parent.visible = false - mainToolBar.height = toolBarHeight - mainToolBar.onToolBarMessageClosed() + _controller.height = toolBarHeight + _controller.onToolBarMessageClosed() } } } diff --git a/src/ui/toolbar/MainToolBar.cc b/src/ui/toolbar/MainToolBarController.cc similarity index 63% rename from src/ui/toolbar/MainToolBar.cc rename to src/ui/toolbar/MainToolBarController.cc index 52a640cce..3ae149475 100644 --- a/src/ui/toolbar/MainToolBar.cc +++ b/src/ui/toolbar/MainToolBarController.cc @@ -30,28 +30,20 @@ This file is part of the QGROUNDCONTROL project #include #include -#include "MainToolBar.h" +#include "MainToolBarController.h" #include "ScreenToolsController.h" #include "MainWindow.h" #include "UASMessageView.h" #include "UASMessageHandler.h" -#include "FlightDisplayView.h" #include "QGCApplication.h" #include "MultiVehicleManager.h" #include "UAS.h" -MainToolBar::MainToolBar(QWidget* parent) - : QGCQmlWidgetHolder(QString(), NULL, parent) +MainToolBarController::MainToolBarController(QObject* parent) + : QObject(parent) , _vehicle(NULL) , _mav(NULL) - , _toolBar(NULL) - , _currentView(ViewNone) , _connectionCount(0) - , _showGPS(true) - , _showMav(true) - , _showMessages(true) - , _showRSSI(true) - , _showBattery(true) , _progressBarValue(0.0f) , _remoteRSSI(0) , _remoteRSSIstore(100.0) @@ -60,108 +52,44 @@ MainToolBar::MainToolBar(QWidget* parent) , _rollDownMessages(0) , _toolbarMessageVisible(false) { - setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding); - setObjectName("MainToolBar"); - setMinimumWidth(MainWindow::instance()->minimumWidth()); - // Get rid of layout default margins - QLayout* pl = layout(); - if(pl) { - pl->setContentsMargins(0,0,0,0); - } - setMinimumHeight(ScreenToolsController::defaultFontPixelSize_s() * 3); - setMaximumHeight(ScreenToolsController::defaultFontPixelSize_s() * 3); - // Tool Bar Preferences - QSettings settings; - settings.beginGroup(TOOL_BAR_SETTINGS_GROUP); - _showBattery = settings.value(TOOL_BAR_SHOW_BATTERY, true).toBool(); - _showGPS = settings.value(TOOL_BAR_SHOW_GPS, true).toBool(); - _showMav = settings.value(TOOL_BAR_SHOW_MAV, true).toBool(); - _showMessages = settings.value(TOOL_BAR_SHOW_MESSAGES, true).toBool(); - settings.endGroup(); - - setContextPropertyObject("mainToolBar", this); - setSource(QUrl::fromUserInput("qrc:/qml/MainToolBar.qml")); - setVisible(true); emit configListChanged(); emit connectionCountChanged(_connectionCount); _activeVehicleChanged(MultiVehicleManager::instance()->activeVehicle()); // Link signals - connect(LinkManager::instance(), &LinkManager::linkConfigurationChanged, this, &MainToolBar::_updateConfigurations); - connect(LinkManager::instance(), &LinkManager::linkConnected, this, &MainToolBar::_linkConnected); - connect(LinkManager::instance(), &LinkManager::linkDisconnected, this, &MainToolBar::_linkDisconnected); + connect(LinkManager::instance(), &LinkManager::linkConfigurationChanged, this, &MainToolBarController::_updateConfigurations); + connect(LinkManager::instance(), &LinkManager::linkConnected, this, &MainToolBarController::_linkConnected); + connect(LinkManager::instance(), &LinkManager::linkDisconnected, this, &MainToolBarController::_linkDisconnected); // RSSI (didn't like standard connection) connect(MAVLinkProtocol::instance(), SIGNAL(radioStatusChanged(LinkInterface*, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned)), this, SLOT(_telemetryChanged(LinkInterface*, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned, unsigned))); - connect(MultiVehicleManager::instance(), &MultiVehicleManager::activeVehicleChanged, this, &MainToolBar::_activeVehicleChanged); - - connect(this, &MainToolBar::heightChanged, this, &MainToolBar::_heightChanged); + connect(MultiVehicleManager::instance(), &MultiVehicleManager::activeVehicleChanged, this, &MainToolBarController::_activeVehicleChanged); } -MainToolBar::~MainToolBar() +MainToolBarController::~MainToolBarController() { } -void MainToolBar::_setToolBarState(const QString& key, bool value) +void MainToolBarController::onSetupView() { - QSettings settings; - settings.beginGroup(TOOL_BAR_SETTINGS_GROUP); - settings.setValue(key, value); - settings.endGroup(); - if(key == TOOL_BAR_SHOW_GPS) { - _showGPS = value; - emit showGPSChanged(value); - } else if(key == TOOL_BAR_SHOW_MAV) { - _showMav = value; - emit showMavChanged(value); - }else if(key == TOOL_BAR_SHOW_BATTERY) { - _showBattery = value; - emit showBatteryChanged(value); - } else if(key == TOOL_BAR_SHOW_MESSAGES) { - _showMessages = value; - emit showMessagesChanged(value); - } else if(key == TOOL_BAR_SHOW_RSSI) { - _showRSSI = value; - emit showRSSIChanged(value); - } + MainWindow::instance()->showSetupView(); } -void MainToolBar::viewStateChanged(const QString &key, bool value) +void MainToolBarController::onPlanView() { - _setToolBarState(key, value); + MainWindow::instance()->showPlanView(); } -void MainToolBar::onSetupView() +void MainToolBarController::onFlyView() { - setCurrentView(MainWindow::VIEW_SETUP); - MainWindow::instance()->loadSetupView(); -} - -void MainToolBar::onPlanView() -{ - setCurrentView(MainWindow::VIEW_MISSIONEDITOR); - MainWindow::instance()->loadPlanView(); -} - -void MainToolBar::onFlyView() -{ - setCurrentView(MainWindow::VIEW_FLIGHT); - MainWindow::instance()->loadFlightView(); -} - -void MainToolBar::onFlyViewMenu() -{ - FlightDisplayView* fdsp = MainWindow::instance()->getFlightDisplay(); - if(fdsp) { - fdsp->showOptionsMenu(); - } + MainWindow::instance()->showFlyView(); } -void MainToolBar::onDisconnect(QString conf) +void MainToolBarController::onDisconnect(QString conf) { if(conf.isEmpty()) { // Disconnect Only Connected Link @@ -191,7 +119,7 @@ void MainToolBar::onDisconnect(QString conf) } } -void MainToolBar::onConnect(QString conf) +void MainToolBarController::onConnect(QString conf) { // Connect Link if(conf.isEmpty()) { @@ -209,64 +137,48 @@ void MainToolBar::onConnect(QString conf) } } -void MainToolBar::onEnterMessageArea(int x, int y) +void MainToolBarController::onEnterMessageArea(int x, int y) { + Q_UNUSED(x); + Q_UNUSED(y); + // If not already there and messages are actually present - if(!_rollDownMessages && UASMessageHandler::instance()->messages().count()) - { - if (MultiVehicleManager::instance()->activeVehicle()) + if(!_rollDownMessages && UASMessageHandler::instance()->messages().count()) { + if (MultiVehicleManager::instance()->activeVehicle()) { MultiVehicleManager::instance()->activeVehicle()->resetMessages(); + } + + // FIXME: Position of the message dropdown is hacked right now to speed up Qml conversion // Show messages int dialogWidth = 400; +#if 0 x = x - (dialogWidth >> 1); if(x < 0) x = 0; y = height() / 3; +#endif + // Put dialog on top of the message alert icon - QPoint p = mapToGlobal(QPoint(x,y)); _rollDownMessages = new UASMessageViewRollDown(MainWindow::instance()); _rollDownMessages->setAttribute(Qt::WA_DeleteOnClose); - _rollDownMessages->move(mapFromGlobal(p)); + _rollDownMessages->move(QPoint(100, 100)); _rollDownMessages->setMinimumSize(dialogWidth,200); - connect(_rollDownMessages, &UASMessageViewRollDown::closeWindow, this, &MainToolBar::_leaveMessageView); + connect(_rollDownMessages, &UASMessageViewRollDown::closeWindow, this, &MainToolBarController::_leaveMessageView); _rollDownMessages->show(); } } -void MainToolBar::_leaveMessageView() +void MainToolBarController::_leaveMessageView() { // Mouse has left the message window area (and it has closed itself) _rollDownMessages = NULL; } -void MainToolBar::setCurrentView(int currentView) -{ - ViewType_t view = ViewNone; - switch((MainWindow::VIEW_SECTIONS)currentView) { - case MainWindow::VIEW_MISSIONEDITOR: - view = ViewPlan; - break; - case MainWindow::VIEW_FLIGHT: - view = ViewFly; - break; - case MainWindow::VIEW_SETUP: - view = ViewSetup; - break; - default: - view = ViewNone; - break; - } - if(view != _currentView) { - _currentView = view; - emit currentViewChanged(); - } -} - -void MainToolBar::_activeVehicleChanged(Vehicle* vehicle) +void MainToolBarController::_activeVehicleChanged(Vehicle* vehicle) { // Disconnect the previous one (if any) if (_vehicle) { - disconnect(_mav, &UASInterface::remoteControlRSSIChanged, this, &MainToolBar::_remoteControlRSSIChanged); - disconnect(_vehicle->autopilotPlugin(), &AutoPilotPlugin::parameterListProgress, this, &MainToolBar::_setProgressBarValue); + disconnect(_mav, &UASInterface::remoteControlRSSIChanged, this, &MainToolBarController::_remoteControlRSSIChanged); + disconnect(_vehicle->autopilotPlugin(), &AutoPilotPlugin::parameterListProgress, this, &MainToolBarController::_setProgressBarValue); _mav = NULL; _vehicle = NULL; } @@ -276,12 +188,12 @@ void MainToolBar::_activeVehicleChanged(Vehicle* vehicle) { _vehicle = vehicle; _mav = vehicle->uas(); - connect(_mav, &UASInterface::remoteControlRSSIChanged, this, &MainToolBar::_remoteControlRSSIChanged); - connect(_vehicle->autopilotPlugin(), &AutoPilotPlugin::parameterListProgress, this, &MainToolBar::_setProgressBarValue); + connect(_mav, &UASInterface::remoteControlRSSIChanged, this, &MainToolBarController::_remoteControlRSSIChanged); + connect(_vehicle->autopilotPlugin(), &AutoPilotPlugin::parameterListProgress, this, &MainToolBarController::_setProgressBarValue); } } -void MainToolBar::_updateConfigurations() +void MainToolBarController::_updateConfigurations() { QStringList tmpList; QList configs = LinkManager::instance()->getLinkConfigurationList(); @@ -301,7 +213,7 @@ void MainToolBar::_updateConfigurations() } } -void MainToolBar::_telemetryChanged(LinkInterface*, unsigned, unsigned, unsigned rssi, unsigned remrssi, unsigned, unsigned, unsigned) +void MainToolBarController::_telemetryChanged(LinkInterface*, unsigned, unsigned, unsigned rssi, unsigned remrssi, unsigned, unsigned, unsigned) { // We only care if we haveone single connection if(_connectionCount == 1) { @@ -318,7 +230,7 @@ void MainToolBar::_telemetryChanged(LinkInterface*, unsigned, unsigned, unsigned } } -void MainToolBar::_remoteControlRSSIChanged(uint8_t rssi) +void MainToolBarController::_remoteControlRSSIChanged(uint8_t rssi) { // We only care if we have one single connection if(_connectionCount == 1) { @@ -335,17 +247,17 @@ void MainToolBar::_remoteControlRSSIChanged(uint8_t rssi) } } -void MainToolBar::_linkConnected(LinkInterface*) +void MainToolBarController::_linkConnected(LinkInterface*) { _updateConnection(); } -void MainToolBar::_linkDisconnected(LinkInterface* link) +void MainToolBarController::_linkDisconnected(LinkInterface* link) { _updateConnection(link); } -void MainToolBar::_updateConnection(LinkInterface *disconnectedLink) +void MainToolBarController::_updateConnection(LinkInterface *disconnectedLink) { QStringList connList; int oldCount = _connectionCount; @@ -382,24 +294,18 @@ void MainToolBar::_updateConnection(LinkInterface *disconnectedLink) } } -void MainToolBar::_setProgressBarValue(float value) +void MainToolBarController::_setProgressBarValue(float value) { _progressBarValue = value; emit progressBarValueChanged(value); } -void MainToolBar::_heightChanged(double height) -{ - setMinimumHeight(height); - setMaximumHeight(height); -} - -void MainToolBar::showToolBarMessage(const QString& message) +void MainToolBarController::showToolBarMessage(const QString& message) { _toolbarMessageQueueMutex.lock(); if (_toolbarMessageQueue.count() == 0 && !_toolbarMessageVisible) { - QTimer::singleShot(500, this, &MainToolBar::_delayedShowToolBarMessage); + QTimer::singleShot(500, this, &MainToolBarController::_delayedShowToolBarMessage); } _toolbarMessageQueue += message; @@ -407,7 +313,7 @@ void MainToolBar::showToolBarMessage(const QString& message) _toolbarMessageQueueMutex.unlock(); } -void MainToolBar::_delayedShowToolBarMessage(void) +void MainToolBarController::_delayedShowToolBarMessage(void) { QString messages; @@ -428,7 +334,7 @@ void MainToolBar::_delayedShowToolBarMessage(void) } } -void MainToolBar::onToolBarMessageClosed(void) +void MainToolBarController::onToolBarMessageClosed(void) { _toolbarMessageVisible = false; _delayedShowToolBarMessage(); diff --git a/src/ui/toolbar/MainToolBar.h b/src/ui/toolbar/MainToolBarController.h similarity index 71% rename from src/ui/toolbar/MainToolBar.h rename to src/ui/toolbar/MainToolBarController.h index 63e800c59..43d296632 100644 --- a/src/ui/toolbar/MainToolBar.h +++ b/src/ui/toolbar/MainToolBarController.h @@ -27,10 +27,13 @@ This file is part of the QGROUNDCONTROL project * @author Gus Grubba */ -#ifndef MAINTOOLBAR_H -#define MAINTOOLBAR_H +#ifndef MainToolBarController_H +#define MainToolBarController_H -#include "QGCQmlWidgetHolder.h" +#include + +#include "Vehicle.h" +#include "UASMessageView.h" #define TOOL_BAR_SETTINGS_GROUP "TOOLBAR_SETTINGS_GROUP" #define TOOL_BAR_SHOW_BATTERY "ShowBattery" @@ -39,52 +42,31 @@ This file is part of the QGROUNDCONTROL project #define TOOL_BAR_SHOW_MESSAGES "ShowMessages" #define TOOL_BAR_SHOW_RSSI "ShowRSSI" -class UASInterface; -class UASMessage; -class UASMessageViewRollDown; - -class MainToolBar : public QGCQmlWidgetHolder +class MainToolBarController : public QObject { Q_OBJECT - Q_ENUMS(ViewType_t) -public: - typedef enum { - ViewNone = -1, - ViewAnalyze, // MainWindow::VIEW_ENGINEER - ViewPlan , // MainWindow::VIEW_MISSION_EDITOR - ViewFly , // MainWindow::VIEW_FLIGHT - ViewSetup , // MainWindow::VIEW_SETUP - } ViewType_t; - - MainToolBar(QWidget* parent = NULL); - ~MainToolBar(); +public: + MainToolBarController(QObject* parent = NULL); + ~MainToolBarController(); Q_INVOKABLE void onSetupView(); Q_INVOKABLE void onPlanView(); Q_INVOKABLE void onFlyView(); - Q_INVOKABLE void onFlyViewMenu(); Q_INVOKABLE void onConnect(QString conf); Q_INVOKABLE void onDisconnect(QString conf); Q_INVOKABLE void onEnterMessageArea(int x, int y); Q_INVOKABLE void onToolBarMessageClosed(void); Q_PROPERTY(double height MEMBER _toolbarHeight NOTIFY heightChanged) - Q_PROPERTY(ViewType_t currentView MEMBER _currentView NOTIFY currentViewChanged) Q_PROPERTY(QStringList configList MEMBER _linkConfigurations NOTIFY configListChanged) Q_PROPERTY(int connectionCount READ connectionCount NOTIFY connectionCountChanged) Q_PROPERTY(QStringList connectedList MEMBER _connectedList NOTIFY connectedListChanged) - Q_PROPERTY(bool showGPS MEMBER _showGPS NOTIFY showGPSChanged) - Q_PROPERTY(bool showMav MEMBER _showMav NOTIFY showMavChanged) - Q_PROPERTY(bool showMessages MEMBER _showMessages NOTIFY showMessagesChanged) - Q_PROPERTY(bool showBattery MEMBER _showBattery NOTIFY showBatteryChanged) - Q_PROPERTY(bool showRSSI MEMBER _showRSSI NOTIFY showRSSIChanged) Q_PROPERTY(float progressBarValue MEMBER _progressBarValue NOTIFY progressBarValueChanged) Q_PROPERTY(int remoteRSSI READ remoteRSSI NOTIFY remoteRSSIChanged) Q_PROPERTY(int telemetryRRSSI READ telemetryRRSSI NOTIFY telemetryRRSSIChanged) Q_PROPERTY(int telemetryLRSSI READ telemetryLRSSI NOTIFY telemetryLRSSIChanged) - void setCurrentView (int currentView); void viewStateChanged (const QString& key, bool value); int remoteRSSI () { return _remoteRSSI; } int telemetryRRSSI () { return _telemetryRRSSI; } @@ -95,14 +77,8 @@ public: signals: void connectionCountChanged (int count); - void currentViewChanged (); void configListChanged (); void connectedListChanged (QStringList connectedList); - void showGPSChanged (bool value); - void showMavChanged (bool value); - void showMessagesChanged (bool value); - void showBatteryChanged (bool value); - void showRSSIChanged (bool value); void progressBarValueChanged (float value); void remoteRSSIChanged (int value); void telemetryRRSSIChanged (int value); @@ -121,26 +97,17 @@ private slots: void _setProgressBarValue (float value); void _remoteControlRSSIChanged (uint8_t rssi); void _telemetryChanged (LinkInterface* link, unsigned rxerrors, unsigned fixed, unsigned rssi, unsigned remrssi, unsigned txbuf, unsigned noise, unsigned remnoise); - void _heightChanged (double height); void _delayedShowToolBarMessage (void); private: void _updateConnection (LinkInterface *disconnectedLink = NULL); - void _setToolBarState (const QString& key, bool value); private: Vehicle* _vehicle; UASInterface* _mav; - QQuickItem* _toolBar; - ViewType_t _currentView; QStringList _linkConfigurations; int _connectionCount; QStringList _connectedList; - bool _showGPS; - bool _showMav; - bool _showMessages; - bool _showRSSI; - bool _showBattery; float _progressBarValue; int _remoteRSSI; double _remoteRSSIstore; @@ -155,4 +122,4 @@ private: QMutex _toolbarMessageQueueMutex; }; -#endif // MAINTOOLBAR_H +#endif // MainToolBarController_H diff --git a/src/ui/uas/UASMessageView.cc b/src/ui/uas/UASMessageView.cc index 43591601a..4e001c4c4 100644 --- a/src/ui/uas/UASMessageView.cc +++ b/src/ui/uas/UASMessageView.cc @@ -24,7 +24,6 @@ This file is part of the QGROUNDCONTROL project #include #include -#include "MainToolBar.h" #include "UASMessageView.h" #include "QGCUnconnectedInfoWidget.h" #include "UASMessageHandler.h" -- 2.22.0