Commit 4d13d78e authored by dogmaphobic's avatar dogmaphobic

Experimental mapping/planning tool.

parent f6c0565b
......@@ -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
}
}
This diff is collapsed.
......@@ -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