Commit 383b4aa3 authored by Don Gagne's avatar Don Gagne
Browse files

Merge pull request #1450 from dogmaphobic/mapView

Experimental mapping/planning tool.
parents f6c0565b 4317c4f2
......@@ -156,6 +156,7 @@ INCLUDEPATH += \
src/ui/main \
src/ui/toolbar \
src/ui/flightdisplay \
src/ui/mapdisplay \
src/VehicleSetup \
src/AutoPilotPlugins \
src/QmlControls
......@@ -379,7 +380,8 @@ HEADERS += \
src/ui/toolbar/MainToolBar.h \
src/QmlControls/ScreenTools.h \
src/QGCLoggingCategory.h \
src/ui/flightdisplay/QGCFlightDisplay.h
src/ui/flightdisplay/QGCFlightDisplay.h \
src/ui/mapdisplay/QGCMapDisplay.h
SOURCES += \
src/main.cc \
......@@ -519,7 +521,8 @@ SOURCES += \
src/ui/toolbar/MainToolBar.cc \
src/QmlControls/ScreenTools.cc \
src/QGCLoggingCategory.cc \
src/ui/flightdisplay/QGCFlightDisplay.cc
src/ui/flightdisplay/QGCFlightDisplay.cc \
src/ui/mapdisplay/QGCMapDisplay.cc
#
# Unit Test specific configuration goes here
......
......@@ -87,28 +87,36 @@
<file alias="PowerComponentBattery_04cell.svg">src/AutoPilotPlugins/PX4/Images/PowerComponentBattery_04cell.svg</file>
<file alias="PowerComponentBattery_05cell.svg">src/AutoPilotPlugins/PX4/Images/PowerComponentBattery_05cell.svg</file>
<file alias="PowerComponentBattery_06cell.svg">src/AutoPilotPlugins/PX4/Images/PowerComponentBattery_06cell.svg</file>
<!-- QML Main UI -->
<file alias="MainToolBar.qml">src/ui/toolbar/MainToolBar.qml</file>
<file alias="FlightDisplay.qml">src/ui/flightdisplay/FlightDisplay.qml</file>
<file alias="QGroundControl/HUDControls/qmldir">src/ui/flightdisplay/components/qmldir</file>
<file alias="QGroundControl/HUDControls/QGCAltitudeWidget.qml">src/ui/flightdisplay/components/QGCAltitudeWidget.qml</file>
<file alias="QGroundControl/HUDControls/QGCAttitudeWidget.qml">src/ui/flightdisplay/components/QGCAttitudeWidget.qml</file>
<file alias="QGroundControl/HUDControls/QGCCompass.qml">src/ui/flightdisplay/components/QGCCompass.qml</file>
<file alias="QGroundControl/HUDControls/QGCCurrentAltitude.qml">src/ui/flightdisplay/components/QGCCurrentAltitude.qml</file>
<file alias="QGroundControl/HUDControls/QGCCurrentSpeed.qml">src/ui/flightdisplay/components/QGCCurrentSpeed.qml</file>
<file alias="QGroundControl/HUDControls/QGCMapBackground.qml">src/ui/flightdisplay/components/QGCMapBackground.qml</file>
<file alias="QGroundControl/HUDControls/QGCPitchWidget.qml">src/ui/flightdisplay/components/QGCPitchWidget.qml</file>
<file alias="QGroundControl/HUDControls/QGCSpeedWidget.qml">src/ui/flightdisplay/components/QGCSpeedWidget.qml</file>
<file alias="QGroundControl/HUDControls/QGCSlider.qml">src/ui/flightdisplay/components/QGCSlider.qml</file>
<file alias="compass.svg">src/ui/flightdisplay/components/compass.svg</file>
<file alias="compassNeedle.svg">src/ui/flightdisplay/components/compassNeedle.svg</file>
<file alias="crossHair.svg">src/ui/flightdisplay/components/crossHair.svg</file>
<file alias="rollDial.svg">src/ui/flightdisplay/components/rollDial.svg</file>
<file alias="rollDialWhite.svg">src/ui/flightdisplay/components/rollDialWhite.svg</file>
<file alias="rollPointer.svg">src/ui/flightdisplay/components/rollPointer.svg</file>
<file alias="rollPointerWhite.svg">src/ui/flightdisplay/components/rollPointerWhite.svg</file>
<file alias="scale.png">src/ui/flightdisplay/components/scale.png</file>
<file alias="scale_end.png">src/ui/flightdisplay/components/scale_end.png</file>
<file alias="MapDisplay.qml">src/ui/mapdisplay/MapDisplay.qml</file>
<!-- QML Main UI Components -->
<file alias="QGroundControl/FlightControls/qmldir">src/ui/qmlcommon/qmldir</file>
<file alias="QGroundControl/FlightControls/QGCAltitudeWidget.qml">src/ui/qmlcommon/QGCAltitudeWidget.qml</file>
<file alias="QGroundControl/FlightControls/QGCAttitudeWidget.qml">src/ui/qmlcommon/QGCAttitudeWidget.qml</file>
<file alias="QGroundControl/FlightControls/QGCCompass.qml">src/ui/qmlcommon/QGCCompass.qml</file>
<file alias="QGroundControl/FlightControls/QGCCurrentAltitude.qml">src/ui/qmlcommon/QGCCurrentAltitude.qml</file>
<file alias="QGroundControl/FlightControls/QGCCurrentSpeed.qml">src/ui/qmlcommon/QGCCurrentSpeed.qml</file>
<file alias="QGroundControl/FlightControls/QGCMapBackground.qml">src/ui/qmlcommon/QGCMapBackground.qml</file>
<file alias="QGroundControl/FlightControls/QGCPitchWidget.qml">src/ui/qmlcommon/QGCPitchWidget.qml</file>
<file alias="QGroundControl/FlightControls/QGCSpeedWidget.qml">src/ui/qmlcommon/QGCSpeedWidget.qml</file>
<file alias="QGroundControl/FlightControls/QGCSlider.qml">src/ui/qmlcommon/QGCSlider.qml</file>
<file alias="QGroundControl/FlightControls/QGCWaypointEditor.qml">src/ui/qmlcommon/QGCWaypointEditor.qml</file>
<file alias="QGroundControl/FlightControls/QGCMapToolButton.qml">src/ui/qmlcommon/QGCMapToolButton.qml</file>
<!-- QML Main UI Resources -->
<file alias="compass.svg">src/ui/qmlcommon/compass.svg</file>
<file alias="compassNeedle.svg">src/ui/qmlcommon/compassNeedle.svg</file>
<file alias="crossHair.svg">src/ui/qmlcommon/crossHair.svg</file>
<file alias="rollDial.svg">src/ui/qmlcommon/rollDial.svg</file>
<file alias="rollDialWhite.svg">src/ui/qmlcommon/rollDialWhite.svg</file>
<file alias="rollPointer.svg">src/ui/qmlcommon/rollPointer.svg</file>
<file alias="rollPointerWhite.svg">src/ui/qmlcommon/rollPointerWhite.svg</file>
<file alias="scale.png">src/ui/qmlcommon/scale.png</file>
<file alias="scale_end.png">src/ui/qmlcommon/scale_end.png</file>
<file alias="buttonLeft.svg">src/ui/qmlcommon/buttonLeft.svg</file>
<file alias="buttonRight.svg">src/ui/qmlcommon/buttonRight.svg</file>
<file alias="buttonHome.svg">src/ui/qmlcommon/buttonHome.svg</file>
</qresource>
<qresource prefix="/AutoPilotPlugins/PX4">
......
......@@ -23,20 +23,21 @@ Item {
property alias status: image.status
property alias verticalAlignment: image.verticalAlignment
width: image.width
width: image.width
height: image.height
Image {
id: image
smooth: true
mipmap: true
visible: false
anchors.fill: parent
id: image
smooth: true
mipmap: true
antialiasing: true
visible: false
anchors.fill: parent
}
ColorOverlay {
anchors.fill: image
source: image
color: parent.color
anchors.fill: image
source: image
color: parent.color
}
}
......@@ -51,6 +51,7 @@ This file is part of the QGROUNDCONTROL project
#include "QGCMAVLinkLogPlayer.h"
#include "SettingsDialog.h"
#include "QGCMapTool.h"
#include "QGCMapDisplay.h"
#include "MAVLinkDecoder.h"
#include "QGCMAVLinkMessageSender.h"
#include "QGCRGBDView.h"
......@@ -151,6 +152,7 @@ MainWindow::MainWindow(QSplashScreen* splashScreen)
// Setup central widget with a layout to hold the views
_centralLayout = new QVBoxLayout();
_centralLayout->setContentsMargins(0,0,0,0);
centralWidget()->setLayout(_centralLayout);
// Set dock options
setDockOptions(AnimatedDocks | AllowTabbedDocks | AllowNestedDocks);
......@@ -263,18 +265,18 @@ MainWindow::MainWindow(QSplashScreen* splashScreen)
// Set OS dependent keyboard shortcuts for the main window, non OS dependent shortcuts are set in MainWindow.ui
#ifdef Q_OS_MACX
_ui.actionSetup->setShortcut(QApplication::translate("MainWindow", "Meta+1", 0));
_ui.actionMissionView->setShortcut(QApplication::translate("MainWindow", "Meta+2", 0));
_ui.actionFlightView->setShortcut(QApplication::translate("MainWindow", "Meta+3", 0));
_ui.actionEngineersView->setShortcut(QApplication::translate("MainWindow", "Meta+4", 0));
_ui.actionPlan->setShortcut(QApplication::translate("MainWindow", "Meta+2", 0));
_ui.actionFlight->setShortcut(QApplication::translate("MainWindow", "Meta+3", 0));
_ui.actionAnalyze->setShortcut(QApplication::translate("MainWindow", "Meta+4", 0));
_ui.actionLocal3DView->setShortcut(QApplication::translate("MainWindow", "Meta+5", 0));
_ui.actionTerminalView->setShortcut(QApplication::translate("MainWindow", "Meta+6", 0));
_ui.actionSimulationView->setShortcut(QApplication::translate("MainWindow", "Meta+7", 0));
_ui.actionFullscreen->setShortcut(QApplication::translate("MainWindow", "Meta+Return", 0));
#else
_ui.actionSetup->setShortcut(QApplication::translate("MainWindow", "Ctrl+1", 0));
_ui.actionMissionView->setShortcut(QApplication::translate("MainWindow", "Ctrl+2", 0));
_ui.actionFlightView->setShortcut(QApplication::translate("MainWindow", "Ctrl+3", 0));
_ui.actionEngineersView->setShortcut(QApplication::translate("MainWindow", "Ctrl+4", 0));
_ui.actionPlan->setShortcut(QApplication::translate("MainWindow", "Ctrl+2", 0));
_ui.actionFlight->setShortcut(QApplication::translate("MainWindow", "Ctrl+3", 0));
_ui.actionAnalyze->setShortcut(QApplication::translate("MainWindow", "Ctrl+4", 0));
_ui.actionLocal3DView->setShortcut(QApplication::translate("MainWindow", "Ctrl+5", 0));
_ui.actionTerminalView->setShortcut(QApplication::translate("MainWindow", "Ctrl+6", 0));
_ui.actionSimulationView->setShortcut(QApplication::translate("MainWindow", "Ctrl+7", 0));
......@@ -441,20 +443,28 @@ void MainWindow::_buildCommonWidgets(void)
_buildCustomWidgets();
}
void MainWindow::_buildPlannerView(void)
void MainWindow::_buildPlanView(void)
{
if (!_plannerView) {
_plannerView = new QGCMapTool(this);
_plannerView->setVisible(false);
if (!_planView) {
_planView = new QGCMapTool(this);
_planView->setVisible(false);
}
}
void MainWindow::_buildPilotView(void)
void MainWindow::_buildExperimentalPlanView(void)
{
if (!_pilotView) {
if (!_experimentalPlanView) {
_experimentalPlanView = new QGCMapDisplay(this);
_experimentalPlanView->setVisible(false);
}
}
void MainWindow::_buildFlightView(void)
{
if (!_flightView) {
//_pilotView = new PrimaryFlightDisplay(this);
_pilotView = new QGCFlightDisplay(this);
_pilotView->setVisible(false);
_flightView = new QGCFlightDisplay(this);
_flightView->setVisible(false);
}
}
......@@ -466,11 +476,11 @@ void MainWindow::_buildSetupView(void)
}
}
void MainWindow::_buildEngineeringView(void)
void MainWindow::_buildAnalyzeView(void)
{
if (!_engineeringView) {
_engineeringView = new QGCDataPlot2D(this);
_engineeringView->setVisible(false);
if (!_analyzeView) {
_analyzeView = new QGCDataPlot2D(this);
_analyzeView->setVisible(false);
}
}
......@@ -726,8 +736,9 @@ void MainWindow::loadSettings()
// Select the proper view. Default to the flight view or load the last one used if it's supported.
VIEW_SECTIONS currentViewCandidate = (VIEW_SECTIONS) settings.value("CURRENT_VIEW", _currentView).toInt();
switch (currentViewCandidate) {
case VIEW_ENGINEER:
case VIEW_MISSION:
case VIEW_ANALYZE:
case VIEW_PLAN:
case VIEW_EXPERIMENTAL_PLAN:
case VIEW_FLIGHT:
case VIEW_SIMULATION:
case VIEW_SETUP:
......@@ -797,13 +808,14 @@ void MainWindow::connectCommonActions()
{
// Bind together the perspective actions
QActionGroup* perspectives = new QActionGroup(_ui.menuPerspectives);
perspectives->addAction(_ui.actionEngineersView);
perspectives->addAction(_ui.actionFlightView);
perspectives->addAction(_ui.actionAnalyze);
perspectives->addAction(_ui.actionFlight);
perspectives->addAction(_ui.actionSimulationView);
perspectives->addAction(_ui.actionMissionView);
perspectives->addAction(_ui.actionPlan);
perspectives->addAction(_ui.actionSetup);
perspectives->addAction(_ui.actionTerminalView);
perspectives->addAction(_ui.actionLocal3DView);
perspectives->addAction(_ui.actionExperimentalPlanView);
perspectives->setExclusive(true);
/* Hide the actions that are not relevant */
......@@ -812,25 +824,30 @@ void MainWindow::connectCommonActions()
#endif
// Mark the right one as selected
if (_currentView == VIEW_ENGINEER)
if (_currentView == VIEW_ANALYZE)
{
_ui.actionEngineersView->setChecked(true);
_ui.actionEngineersView->activate(QAction::Trigger);
_ui.actionAnalyze->setChecked(true);
_ui.actionAnalyze->activate(QAction::Trigger);
}
if (_currentView == VIEW_FLIGHT)
{
_ui.actionFlightView->setChecked(true);
_ui.actionFlightView->activate(QAction::Trigger);
_ui.actionFlight->setChecked(true);
_ui.actionFlight->activate(QAction::Trigger);
}
if (_currentView == VIEW_SIMULATION)
{
_ui.actionSimulationView->setChecked(true);
_ui.actionSimulationView->activate(QAction::Trigger);
}
if (_currentView == VIEW_MISSION)
if (_currentView == VIEW_PLAN)
{
_ui.actionMissionView->setChecked(true);
_ui.actionMissionView->activate(QAction::Trigger);
_ui.actionPlan->setChecked(true);
_ui.actionPlan->activate(QAction::Trigger);
}
if (_currentView == VIEW_EXPERIMENTAL_PLAN)
{
_ui.actionExperimentalPlanView->setChecked(true);
_ui.actionExperimentalPlanView->activate(QAction::Trigger);
}
if (_currentView == VIEW_SETUP)
{
......@@ -870,10 +887,11 @@ void MainWindow::connectCommonActions()
connect(_ui.actionShutdownMAV, SIGNAL(triggered()), UASManager::instance(), SLOT(shutdownActiveUAS()));
// Views actions
connect(_ui.actionFlightView, SIGNAL(triggered()), this, SLOT(loadPilotView()));
connect(_ui.actionFlight, SIGNAL(triggered()), this, SLOT(loadFlightView()));
connect(_ui.actionSimulationView, SIGNAL(triggered()), this, SLOT(loadSimulationView()));
connect(_ui.actionEngineersView, SIGNAL(triggered()), this, SLOT(loadEngineerView()));
connect(_ui.actionMissionView, SIGNAL(triggered()), this, SLOT(loadOperatorView()));
connect(_ui.actionAnalyze, SIGNAL(triggered()), this, SLOT(loadAnalyzeView()));
connect(_ui.actionPlan, SIGNAL(triggered()), this, SLOT(loadPlanView()));
connect(_ui.actionExperimentalPlanView, SIGNAL(triggered()), this, SLOT(loadOldPlanView()));
connect(_ui.actionLocal3DView, SIGNAL(triggered()), this, SLOT(loadLocal3DView()));
connect(_ui.actionTerminalView,SIGNAL(triggered()),this,SLOT(loadTerminalView()));
......@@ -998,9 +1016,9 @@ void MainWindow::UASCreated(UASInterface* uas)
}
linechartWidget->addSource(mavlinkDecoder);
if (_engineeringView != linechartWidget)
if (_analyzeView != linechartWidget)
{
_engineeringView = linechartWidget;
_analyzeView = linechartWidget;
}
// Reload view state in case new widgets were added
......@@ -1047,24 +1065,31 @@ void MainWindow::_loadCurrentViewState(void)
centerView = _setupView;
break;
case VIEW_ENGINEER:
_buildEngineeringView();
centerView = _engineeringView;
case VIEW_ANALYZE:
_buildAnalyzeView();
centerView = _analyzeView;
defaultWidgets = "MAVLINK_INSPECTOR_DOCKWIDGET,PARAMETER_INTERFACE_DOCKWIDGET,FILE_VIEW_DOCKWIDGET,HEAD_UP_DISPLAY_DOCKWIDGET";
break;
case VIEW_FLIGHT:
_buildPilotView();
centerView = _pilotView;
defaultWidgets = "COMMUNICATION_CONSOLE_DOCKWIDGET,UAS_INFO_INFOVIEW_DOCKWIDGET";
_buildFlightView();
centerView = _flightView;
//defaultWidgets = "COMMUNICATION_CONSOLE_DOCKWIDGET,UAS_INFO_INFOVIEW_DOCKWIDGET";
defaultWidgets.clear();
break;
case VIEW_MISSION:
_buildPlannerView();
centerView = _plannerView;
case VIEW_PLAN:
_buildPlanView();
centerView = _planView;
defaultWidgets = "UNMANNED_SYSTEM_LIST_DOCKWIDGET,WAYPOINT_LIST_DOCKWIDGET";
break;
case VIEW_EXPERIMENTAL_PLAN:
_buildExperimentalPlanView();
centerView = _experimentalPlanView;
defaultWidgets.clear();
break;
case VIEW_SIMULATION:
_buildSimView();
centerView = _simView;
......@@ -1096,6 +1121,7 @@ void MainWindow::_loadCurrentViewState(void)
Q_ASSERT(_centralLayout->count() == 0);
_currentViewWidget = centerView;
_centralLayout->addWidget(_currentViewWidget);
_centralLayout->setContentsMargins(0, 0, 0, 0);
_currentViewWidget->setVisible(true);
// Hide all widgets from previous view
......@@ -1174,27 +1200,39 @@ void MainWindow::handleMisconfiguration(UASInterface* uas)
}
}
void MainWindow::loadEngineerView()
void MainWindow::loadAnalyzeView()
{
if (_currentView != VIEW_ENGINEER)
if (_currentView != VIEW_ANALYZE)
{
_storeCurrentViewState();
_currentView = VIEW_ENGINEER;
_ui.actionEngineersView->setChecked(true);
_currentView = VIEW_ANALYZE;
_ui.actionAnalyze->setChecked(true);
_loadCurrentViewState();
}
}
void MainWindow::loadOperatorView()
void MainWindow::loadPlanView()
{
if (_currentView != VIEW_MISSION)
if (_currentView != VIEW_PLAN)
{
_storeCurrentViewState();
_currentView = VIEW_MISSION;
_ui.actionMissionView->setChecked(true);
_currentView = VIEW_PLAN;
_ui.actionPlan->setChecked(true);
_loadCurrentViewState();
}
}
void MainWindow::loadOldPlanView()
{
if (_currentView != VIEW_EXPERIMENTAL_PLAN)
{
_storeCurrentViewState();
_currentView = VIEW_EXPERIMENTAL_PLAN;
_ui.actionExperimentalPlanView->setChecked(true);
_loadCurrentViewState();
}
}
void MainWindow::loadSetupView()
{
if (_currentView != VIEW_SETUP)
......@@ -1228,13 +1266,13 @@ void MainWindow::loadLocal3DView()
}
}
void MainWindow::loadPilotView()
void MainWindow::loadFlightView()
{
if (_currentView != VIEW_FLIGHT)
{
_storeCurrentViewState();
_currentView = VIEW_FLIGHT;
_ui.actionFlightView->setChecked(true);
_ui.actionFlight->setChecked(true);
_loadCurrentViewState();
}
}
......
......@@ -146,13 +146,15 @@ public slots:
/** @brief Load configuration views */
void loadSetupView();
/** @brief Load view for pilot */
void loadPilotView();
void loadFlightView();
/** @brief Load view for simulation */
void loadSimulationView();
/** @brief Load view for engineer */
void loadEngineerView();
/** @brief Load view for operator */
void loadOperatorView();
void loadAnalyzeView();
/** @brief Load New (QtQuick) Map View (Mission) */
void loadPlanView();
/** @brief Load Old (Qt Widget) Map View (Mission) */
void loadOldPlanView();
/** @brief Load Terminal Console views */
void loadTerminalView();
/** @brief Load local 3D view */
......@@ -220,13 +222,14 @@ protected:
typedef enum _VIEW_SECTIONS
{
VIEW_ENGINEER, // Engineering/Analyze view mode. Used for analyzing data and modifying onboard parameters
VIEW_MISSION, // Mission/Map/Plan view mode. Used for setting mission waypoints and high-level system commands.
VIEW_ANALYZE, // Engineering/Analyze view mode. Used for analyzing data and modifying onboard parameters
VIEW_PLAN, // New (QtQuick) Mission/Map/Plan view mode. Used for setting mission waypoints and high-level system commands.
VIEW_FLIGHT, // Flight/Fly/Operate view mode. Used for 1st-person observation of the vehicle.
VIEW_SIMULATION, // HIL Simulation view. Useful overview of the entire system when doing hardware-in-the-loop simulations.
VIEW_SETUP, // Setup view. Used for initializing the system for operation. Includes UI for calibration, firmware updating/checking, and parameter modifcation.
VIEW_TERMINAL, // Terminal interface. Used for communicating with the remote system, usually in a special configuration input mode.
VIEW_LOCAL3D, // A local 3D view. Provides a local 3D view that makes visualizing 3D attitude/orientation/pose easy while in operation.
VIEW_EXPERIMENTAL_PLAN, // Original (Qt Widget) Mission/Map/Plan view mode. Used for setting mission waypoints and high-level system commands.
} VIEW_SECTIONS;
/** @brief Catch window resize events */
......@@ -300,10 +303,11 @@ private:
void _openUrl(const QString& url, const QString& errorMessage);
// Center widgets
QPointer<QWidget> _plannerView;
QPointer<QWidget> _pilotView;
QPointer<QWidget> _planView;
QPointer<QWidget> _experimentalPlanView;
QPointer<QWidget> _flightView;
QPointer<QWidget> _setupView;
QPointer<QWidget> _engineeringView;
QPointer<QWidget> _analyzeView;
QPointer<QWidget> _simView;
QPointer<QWidget> _terminalView;
QPointer<QWidget> _local3DView;
......@@ -329,10 +333,11 @@ private:
QMap<int, QDockWidget*> _mapUasId2HilDockWidget;
QMap<QDockWidget*, QAction*> _mapDockWidget2Action;
void _buildPlannerView(void);
void _buildPilotView(void);
void _buildPlanView(void);
void _buildExperimentalPlanView(void);
void _buildFlightView(void);
void _buildSetupView(void);
void _buildEngineeringView(void);
void _buildAnalyzeView(void);
void _buildSimView(void);
void _buildTerminalView(void);
void _buildLocal3DView(void);
......
......@@ -78,9 +78,9 @@
<string>View</string>
</property>
<addaction name="actionSetup"/>
<addaction name="actionMissionView"/>
<addaction name="actionFlightView"/>
<addaction name="actionEngineersView"/>
<addaction name="actionPlan"/>
<addaction name="actionFlight"/>
<addaction name="actionAnalyze"/>
<addaction name="separator"/>
<addaction name="actionFullscreen"/>
<addaction name="actionNormal"/>
......@@ -99,6 +99,7 @@
<addaction name="actionLoadCustomWidgetFile"/>
<addaction name="separator"/>
</widget>
<addaction name="actionExperimentalPlanView"/>
<addaction name="actionLocal3DView"/>
<addaction name="actionTerminalView"/>
<addaction name="actionSimulationView"/>
......@@ -198,7 +199,7 @@
<string>Developer Credits</string>
</property>
</action>
<action name="actionMissionView">
<action name="actionPlan">
<property name="checkable">
<bool>true</bool>
</property>
......@@ -206,7 +207,7 @@
<string>Plan</string>
</property>
</action>
<action name="actionEngineersView">
<action name="actionAnalyze">
<property name="checkable">
<bool>true</bool>
</property>
......@@ -214,7 +215,7 @@
<string>Analyze</string>
</property>
</action>
<action name="actionFlightView">
<action name="actionFlight">
<property name="checkable">
<bool>true</bool>
</property>
......@@ -345,6 +346,11 @@
<string>Status Bar</string>
</property>
</action>
<action name="actionExperimentalPlanView">
<property name="text">
<string>Experimental Plan View</string>
</property>
</action>
</widget>
<layoutdefault spacing="6" margin="11"/>
<resources>
......
......@@ -23,7 +23,7 @@ This file is part of the QGROUNDCONTROL project
/**
* @file
* @brief QGC Main Tool Bar
* @brief QGC Main Flight Display
* @author Gus Grubba <mavlink@grubba.com>
*/
......@@ -31,7 +31,7 @@ import QtQuick 2.3
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
import QGroundControl.HUDControls 1.0
import QGroundControl.FlightControls 1.0
Rectangle {
id: root
......@@ -285,17 +285,17 @@ Rectangle {
}
QGCMapBackground {
id: mapBackground
anchors.centerIn: parent
visible: false
heading: isNaN(flightDisplay.heading) ? 0 : flightDisplay.heading
latitude: flightDisplay.latitude
longitude: flightDisplay.longitude
z: 5
id: mapBackground
anchors.fill: parent
visible: false
heading: isNaN(flightDisplay.heading) ? 0 : flightDisplay.heading
latitude: flightDisplay.latitude
longitude: flightDisplay.longitude
z: 5
}
QGCAttitudeWidget {
id: attitudeWidget
id: attitudeWidget
anchors.centerIn: parent
rollAngle: roll
pitchAngle: pitch
......@@ -305,7 +305,7 @@ Rectangle {
}
QGCPitchWidget {
id: pitchWidget
id: pitchWidget
anchors.verticalCenter: parent.verticalCenter
pitchAngle: pitch
rollAngle: roll
......
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
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 <http://www.gnu.org/licenses/>.
======================================================================*/
/**
* @file
* @brief QGC Main Map Display
* @author Gus Grubba <mavlink@grubba.com>
*/
import QtQuick 2.3
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
import QtQuick.Layouts 1.1
import QGroundControl.Palette 1.0
import QGroundControl.FlightControls 1.0
Rectangle {
QGCPalette { id: __palette; colorGroupEnabled: true }
id: root
color: Qt.rgba(0,0,0,0);
property real roll: isNaN(mapEngine.roll) ? 0 : mapEngine.roll
property real pitch: isNaN(mapEngine.pitch) ? 0 : mapEngine.pitch
property bool showWaypointEditor: true
function getBool(value) {
return value === '0' ? false : true;
}
function setBool(value) {
return value ? "1" : "0";
}
Component.onCompleted:
{
mapTypeMenu.update();
}
Menu {
id: mapTypeMenu
title: "Map Type..."
ExclusiveGroup { id: currentMapType }
function setCurrentMap(map) {
for (var i = 0; i < mapBackground.mapItem.supportedMapTypes.length; i++) {
if (map === mapBackground.mapItem.supportedMapTypes[i].name) {
mapBackground.mapItem.activeMapType = mapBackground.mapItem.supportedMapTypes[i]
mapEngine.saveSetting("currentMapType", map);
return;
}
}
}
function addMap(map, checked) {
var mItem = mapTypeMenu.addItem(map);
mItem.checkable = true
mItem.checked = checked
mItem.exclusiveGroup = currentMapType
var menuSlot = function() {setCurrentMap(map);};
mItem.triggered.connect(menuSlot);
}
function update() {
clear()
var map = ''
if (mapBackground.mapItem.supportedMapTypes.length > 0)
map = mapBackground.mapItem.activeMapType.name;
map = mapEngine.loadSetting("currentMapType", map);
for (var i = 0; i < mapBackground.mapItem.supportedMapTypes.length; i++) {
var name = mapBackground.mapItem.supportedMapTypes[i].name;
addMap(name, map === name);
}
if(map != '')
setCurrentMap(map);
}
}
SplitView {
id: splitView
anchors.fill: parent
orientation: Qt.Horizontal
z: 10
// This sets the color of the splitter line
handleDelegate: Rectangle {
width: 1
height: 1
color: __palette.window
}
//----------------------------------------------------------------------------------------
// Map View
QGCMapBackground {
id: mapBackground
Layout.fillWidth: true
Layout.minimumWidth: 300
heading: isNaN(mapEngine.heading) ? 0 : mapEngine.heading
latitude: 37.803784 // mapEngine.latitude
longitude: -122.462276 // mapEngine.longitude
// Chevron button at upper right corner of Map Display
Item {
id: openWaypoints
anchors.top: mapBackground.top
anchors.right: mapBackground.right
width: 30
height: 30
opacity: 0.85
z: splitView.z + 10
Image {
id: buttomImg
anchors.fill: parent
source: showWaypointEditor ? "/qml/buttonRight.svg" : "/qml/buttonLeft.svg"
mipmap: true
smooth: true
antialiasing: true
fillMode: Image.PreserveAspectFit
}
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.LeftButton
onClicked: {
if (mouse.button == Qt.LeftButton)
{
showWaypointEditor = !showWaypointEditor
}
}
}
}
}
//----------------------------------------------------------------------------------------
// Waypoint Editor
QGCWaypointEditor {
id: waypointEditor
Layout.minimumWidth: 200
visible: showWaypointEditor
}
}
//--------------------------------------------------------------------------------------------
// Right click anywhere on the map for a context menu
MouseArea {
anchors.fill: parent
acceptedButtons: Qt.RightButton
onClicked: {
if (mouse.button == Qt.RightButton)
{
mapTypeMenu.popup()
}
}
z: splitView.z + 5
}
//--------------------------------------------------------------------------------------------
// Tool Bar
Rectangle {
id: toolBar
color: Qt.rgba(0,0,0,0)
height: buttonColumn.height
visible: showWaypointEditor
anchors.top: parent.top
anchors.left: parent.left
anchors.topMargin: 40
anchors.leftMargin: 4
z: splitView.z + 10
ExclusiveGroup { id: mainActionGroup }
Column {
id: buttonColumn
spacing: 4
QGCMapToolButton {
width: 50
height: 50
imageSource: "/qml/buttonHome.svg"
exclusiveGroup: mainActionGroup
}
QGCMapToolButton {
width: 50
height: 50
imageSource: "/qml/buttonHome.svg"
exclusiveGroup: mainActionGroup
}
QGCMapToolButton {
width: 50
height: 50
imageSource: "/qml/buttonHome.svg"
exclusiveGroup: mainActionGroup
}
QGCMapToolButton {
width: 50
height: 50
imageSource: "/qml/buttonHome.svg"
exclusiveGroup: mainActionGroup
}
}
}
}
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
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 <http://www.gnu.org/licenses/>.
======================================================================*/
/**
* @file
* @brief QGC Main Map Display
* @author Gus Grubba <mavlink@grubba.com>
*/
#include <QQmlContext>
#include <QQmlEngine>
#include <QSettings>
#include "QGCMapDisplay.h"
#include "UASManager.h"
const char* kMainMapDisplayGroup = "MainMapDisplay";
QGCMapDisplay::QGCMapDisplay(QWidget *parent)
: QGCQmlWidgetHolder(parent)
{
setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::MinimumExpanding);
setObjectName("MainMapDisplay");
// Get rid of layout default margins
QLayout* pl = layout();
if(pl) {
pl->setContentsMargins(0,0,0,0);
}
setMinimumWidth(270);
setMinimumHeight(300);
setContextPropertyObject("mapEngine", this);
setSource(QUrl::fromUserInput("qrc:/qml/MapDisplay.qml"));
setVisible(true);
}
QGCMapDisplay::~QGCMapDisplay()
{
}
void QGCMapDisplay::saveSetting(const QString &name, const QString& value)
{
QSettings settings;
QString key(kMainMapDisplayGroup);
key += "/" + name;
settings.setValue(key, value);
}
QString QGCMapDisplay::loadSetting(const QString &name, const QString& defaultValue)
{
QSettings settings;
QString key(kMainMapDisplayGroup);
key += "/" + name;
return settings.value(key, defaultValue).toString();
}
/*
* Internal
*/
void QGCMapDisplay::showEvent(QShowEvent* event)
{
// React only to internal (pre-display) events
QWidget::showEvent(event);
}
void QGCMapDisplay::hideEvent(QHideEvent* event)
{
// React only to internal (pre-display) events
QWidget::hideEvent(event);
}
/*=====================================================================
QGroundControl Open Source Ground Control Station
(c) 2009, 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
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 <http://www.gnu.org/licenses/>.
======================================================================*/
/**
* @file
* @brief QGC Main Map Display
* @author Gus Grubba <mavlink@grubba.com>
*/
#ifndef QGCMAPDISPLAY_H
#define QGCMAPDISPLAY_H
#include "QGCQmlWidgetHolder.h"
class UASInterface;
class UASWaypointManager;
class QGCMapDisplay : public QGCQmlWidgetHolder
{
Q_OBJECT
public:
QGCMapDisplay(QWidget* parent = NULL);
~QGCMapDisplay();
Q_INVOKABLE void saveSetting (const QString &key, const QString& value);
Q_INVOKABLE QString loadSetting (const QString &key, const QString& defaultValue);
/** @brief Start updating widget */
void showEvent(QShowEvent* event);
/** @brief Stop updating widget */
void hideEvent(QHideEvent* event);
signals:
private slots:
private:
private:
UASWaypointManager* WPM;
};
#endif // QGCFLIGHTDISPLAY_H
......@@ -31,18 +31,17 @@ import QtQuick 2.4
import QtPositioning 5.3
import QtLocation 5.3
import QGroundControl.HUDControls 1.0
import QGroundControl.FlightControls 1.0
Rectangle {
id: root
property real latitude: 37.803784
property real longitude : -122.462276
property real zoomLevel: (map.maximumZoomLevel - map.minimumZoomLevel) / 2
property real zoomLevel: 15
property real heading: 0
property bool alwaysNorth: true
property alias mapItem: map
anchors.fill: parent
color: Qt.rgba(0,0,0,0)
clip: true
......
import QtQuick 2.2
import QtQuick.Controls 1.2
import QtQuick.Controls.Styles 1.2
import QtQuick.Controls.Private 1.0
import QGroundControl.Controls 1.0
import QGroundControl.Palette 1.0
import QGroundControl.ScreenTools 1.0
Button {
property var imageSource: undefined
property var __qgcPal: QGCPalette { colorGroupEnabled: enabled }
property bool __showHighlight: (pressed | hovered | checked) && !__forceHoverOff
property ScreenTools __screenTools: ScreenTools { }
// This fixes the issue with button hover where if a Button is near the edge oa QQuickWidget you can
// move the mouse fast enough such that the MouseArea does not trigger an onExited. This is turn
// cause the hover property to not be cleared correctly.
property bool __forceHoverOff: false
property int __lastGlobalMouseX: 0
property int __lastGlobalMouseY: 0
Connections {
target: __behavior
onMouseXChanged: {
__lastGlobalMouseX = __screenTools.mouseX
__lastGlobalMouseY = __screenTools.mouseY
}
onMouseYChanged: {
__lastGlobalMouseX = __screenTools.mouseX
__lastGlobalMouseY = __screenTools.mouseY
}
onEntered: { __forceHoverOff; false; hoverTimer.start() }
onExited: { __forceHoverOff; false; hoverTimer.stop() }
}
Timer {
id: hoverTimer
interval: 250
repeat: true
onTriggered: {
if (__lastGlobalMouseX != __screenTools.mouseX || __lastGlobalMouseY != __screenTools.mouseY) {
__forceHoverOff = true
} else {
__forceHoverOff = false
}
}
}
style: ButtonStyle {
/*! This defines the background of the button. */
background: Item {
property bool __checked: (control.checkable && control.checked)
Rectangle {
id: backgroundRectangle
anchors.fill: parent
color: __showHighlight ? __qgcPal.buttonHighlight : (__checked ? __qgcPal.buttonHighlight : __qgcPal.window);
}
QGCColoredImage {
id: image
anchors.fill: parent
opacity: control.enabled ? 0.6 : 0.5
source: imageSource
color: __showHighlight ? __qgcPal.buttonHighlightText : (__checked ? __qgcPal.primaryButtonText : __qgcPal.buttonText)
}
}
}
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment