Commit 9d4833a3 authored by Don Gagne's avatar Don Gagne

New CenterMapDropButton control

parent 993f5251
......@@ -105,6 +105,7 @@
<file alias="QGroundControl/FlightDisplay/FlightDisplayViewVideo.qml">src/FlightDisplay/FlightDisplayViewVideo.qml</file>
<file alias="QGroundControl/FlightDisplay/FlightDisplayViewWidgets.qml">src/FlightDisplay/FlightDisplayViewWidgets.qml</file>
<file alias="QGroundControl/FlightDisplay/qmldir">src/FlightDisplay/qmldir</file>
<file alias="QGroundControl/FlightMap/CenterMapDropButton.qml">src/FlightMap/Widgets/CenterMapDropButton.qml</file>
<file alias="QGroundControl/FlightMap/FlightMap.qml">src/FlightMap/FlightMap.qml</file>
<file alias="QGroundControl/FlightMap/InstrumentSwipeView.qml">src/FlightMap/Widgets/InstrumentSwipeView.qml</file>
<file alias="QGroundControl/FlightMap/MapScale.qml">src/FlightMap/MapScale.qml</file>
......
......@@ -116,7 +116,6 @@ QGCView {
onActiveVehicleJoystickEnabledChanged: px4JoystickCheck()
Component.onCompleted: {
widgetsLoader.source = "FlightDisplayViewWidgets.qml"
setStates()
px4JoystickCheck()
}
......@@ -153,9 +152,10 @@ QGCView {
}
]
FlightDisplayViewMap {
id: _flightMap
anchors.fill: parent
flightWidgets: widgetsLoader.item
id: _flightMap
anchors.fill: parent
flightWidgets: flightDisplayViewWidgets
rightPanelWidth: ScreenTools.defaultFontPixelHeight * 9
}
}
......@@ -218,16 +218,13 @@ QGCView {
}
}
//-- Widgets
Loader {
id: widgetsLoader
FlightDisplayViewWidgets {
id: flightDisplayViewWidgets
z: _panel.z + 4
height: ScreenTools.availableHeight
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
asynchronous: true
visible: status == Loader.Ready
property bool isBackgroundDark: root.isBackgroundDark
property var qgcView: root
......@@ -242,7 +239,7 @@ QGCView {
visible: QGroundControl.virtualTabletJoystick
anchors.bottom: _flightVideoPipControl.top
anchors.bottomMargin: ScreenTools.defaultFontPixelHeight * 2
anchors.horizontalCenter: widgetsLoader.horizontalCenter
anchors.horizontalCenter: flightDisplayViewWidgets.horizontalCenter
source: "qrc:/qml/VirtualJoystick.qml"
active: QGroundControl.virtualTabletJoystick
......
......@@ -29,6 +29,7 @@ FlightMap {
property alias missionController: missionController
property var flightWidgets
property var rightPanelWidth
property bool _followVehicle: true
property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
......@@ -36,6 +37,7 @@ FlightMap {
property var activeVehicleCoordinate: _activeVehicle ? _activeVehicle.coordinate : QtPositioning.coordinate()
property var _gotoHereCoordinate: QtPositioning.coordinate()
property int _retaskSequence: 0
property real _toolButtonTopMargin: parent.height - ScreenTools.availableHeight + (ScreenTools.defaultFontPixelHeight / 2)
Component.onCompleted: {
QGroundControl.flightMapPosition = center
......@@ -52,6 +54,7 @@ FlightMap {
}
QGCPalette { id: qgcPal; colorGroupEnabled: true }
QGCMapPalette { id: mapPal; lightColors: isSatelliteMap }
MissionController {
id: missionController
......@@ -68,6 +71,144 @@ FlightMap {
Component.onCompleted: start(false /* editMode */)
}
QGCLabel {
id: flyLabel
text: qsTr("Fly")
color: mapPal.text
visible: !ScreenTools.isShortScreen
anchors.topMargin: _toolButtonTopMargin
anchors.horizontalCenter: toolColumn.horizontalCenter
anchors.top: parent.top
}
//-- Vertical Tool Buttons
ExclusiveGroup {
id: dropButtonsExclusiveGroup
}
ExclusiveGroup {
id: mapTypeButtonsExclusiveGroup
}
//-- Dismiss Drop Down (if any)
MouseArea {
anchors.fill: parent
enabled: dropButtonsExclusiveGroup.current != null
onClicked: {
if (dropButtonsExclusiveGroup.current) {
dropButtonsExclusiveGroup.current.checked = false
}
dropButtonsExclusiveGroup.current = null
}
}
Column {
id: toolColumn
anchors.topMargin: ScreenTools.isShortScreen ? _toolButtonTopMargin : ScreenTools.defaultFontPixelHeight / 2
anchors.leftMargin: ScreenTools.defaultFontPixelHeight
anchors.left: parent.left
anchors.top: ScreenTools.isShortScreen ? parent.top : flyLabel.bottom
spacing: ScreenTools.defaultFontPixelHeight
z: QGroundControl.zOrderWidgets
//-- Map Center Control
CenterMapDropButton {
id: centerMapDropButton
exclusiveGroup: dropButtonsExclusiveGroup
map: _flightMap
mapFitViewport: Qt.rect(leftToolWidth, _toolButtonTopMargin, flightMap.width - leftToolWidth - rightPanelWidth, flightMap.height - _toolButtonTopMargin)
usePlannedHomePosition: false
geoFenceController: geoFenceController
missionController: missionController
rallyPointController: rallyPointController
showFollowVehicle: true
followVehicle: _followVehicle
onFollowVehicleChanged: _followVehicle = followVehicle
property real leftToolWidth: centerMapDropButton.x + centerMapDropButton.width
}
//-- Map Type Control
DropButton {
id: mapTypeButton
dropDirection: dropRight
buttonImage: "/qmlimages/MapType.svg"
viewportMargins: ScreenTools.defaultFontPixelWidth / 2
exclusiveGroup: dropButtonsExclusiveGroup
z: QGroundControl.zOrderWidgets
lightBorders: isSatelliteMap
dropDownComponent: Component {
Column {
spacing: ScreenTools.defaultFontPixelWidth
Row {
spacing: ScreenTools.defaultFontPixelWidth
Repeater {
model: QGroundControl.flightMapSettings.mapTypes
QGCButton {
checkable: true
checked: QGroundControl.flightMapSettings.mapType === text
text: modelData
width: clearButton.width
exclusiveGroup: mapTypeButtonsExclusiveGroup
onClicked: {
QGroundControl.flightMapSettings.mapType = text
checked = true
dropButtonsExclusiveGroup.current = null
}
}
}
}
QGCButton {
id: clearButton
text: qsTr("Clear Flight Trails")
enabled: QGroundControl.multiVehicleManager.activeVehicle
onClicked: {
QGroundControl.multiVehicleManager.activeVehicle.clearTrajectoryPoints()
dropButtonsExclusiveGroup.current = null
}
}
}
}
}
//-- Zoom Map In
RoundButton {
id: mapZoomPlus
visible: !ScreenTools.isTinyScreen && _mainIsMap
buttonImage: "/qmlimages/ZoomPlus.svg"
exclusiveGroup: dropButtonsExclusiveGroup
z: QGroundControl.zOrderWidgets
lightBorders: isSatelliteMap
onClicked: {
if(_flightMap)
_flightMap.zoomLevel += 0.5
checked = false
}
}
//-- Zoom Map Out
RoundButton {
id: mapZoomMinus
visible: !ScreenTools.isTinyScreen && _mainIsMap
buttonImage: "/qmlimages/ZoomMinus.svg"
exclusiveGroup: dropButtonsExclusiveGroup
z: QGroundControl.zOrderWidgets
lightBorders: isSatelliteMap
onClicked: {
if(_flightMap)
_flightMap.zoomLevel -= 0.5
checked = false
}
}
}
// Add trajectory points to the map
MapItemView {
model: _mainIsMap ? _activeVehicle ? _activeVehicle.trajectoryPoints : 0 : 0
......
......@@ -34,7 +34,6 @@ Item {
property bool _useAlternateInstruments: QGroundControl.virtualTabletJoystick || ScreenTools.isTinyScreen
readonly property real _margins: ScreenTools.defaultFontPixelHeight / 2
readonly property real _toolButtonTopMargin: parent.height - ScreenTools.availableHeight + (ScreenTools.defaultFontPixelHeight / 2)
QGCMapPalette { id: mapPal; lightColors: isBackgroundDark }
QGCPalette { id: qgcPal }
......@@ -47,14 +46,6 @@ Item {
return Math.min(w, 200)
}
ExclusiveGroup {
id: _dropButtonsExclusiveGroup
}
ExclusiveGroup {
id: _mapTypeButtonsExclusiveGroup
}
//-- Map warnings
Column {
anchors.horizontalCenter: parent.horizontalCenter
......@@ -80,17 +71,6 @@ Item {
}
}
//-- Dismiss Drop Down (if any)
MouseArea {
anchors.fill: parent
enabled: _dropButtonsExclusiveGroup.current != null
onClicked: {
if(_dropButtonsExclusiveGroup.current)
_dropButtonsExclusiveGroup.current.checked = false
_dropButtonsExclusiveGroup.current = null
}
}
//-- Instrument Panel
QGCInstrumentWidget {
id: instrumentGadget
......@@ -139,149 +119,6 @@ Item {
maxHeight: virtualJoystickMultiTouch.visible ? virtualJoystickMultiTouch.y - y : parent.height - anchors.margins - y
}
QGCLabel {
id: flyLabel
text: qsTr("Fly")
color: mapPal.text
visible: !ScreenTools.isShortScreen && _mainIsMap
anchors.topMargin: _toolButtonTopMargin
anchors.horizontalCenter: toolColumn.horizontalCenter
anchors.top: parent.top
}
//-- Vertical Tool Buttons
Column {
id: toolColumn
anchors.topMargin: ScreenTools.isShortScreen ? _toolButtonTopMargin : ScreenTools.defaultFontPixelHeight / 2
anchors.leftMargin: ScreenTools.defaultFontPixelHeight
anchors.left: parent.left
anchors.top: ScreenTools.isShortScreen ? parent.top : flyLabel.bottom
spacing: ScreenTools.defaultFontPixelHeight
visible: _mainIsMap
//-- Map Center Control
DropButton {
id: centerMapDropButton
dropDirection: dropRight
buttonImage: "/qmlimages/MapCenter.svg"
viewportMargins: ScreenTools.defaultFontPixelWidth / 2
exclusiveGroup: _dropButtonsExclusiveGroup
z: QGroundControl.zOrderWidgets
lightBorders: _lightWidgetBorders
dropDownComponent: Component {
Row {
spacing: ScreenTools.defaultFontPixelWidth
QGCCheckBox {
id: followVehicleCheckBox
text: qsTr("Follow Vehicle")
checked: _flightMap ? _flightMap._followVehicle : false
anchors.verticalCenter: parent.verticalCenter
//anchors.baseline: centerMapButton.baseline - This doesn't work correctly on mobile for some strange reason, so we center instead
onClicked: {
_dropButtonsExclusiveGroup.current = null
_flightMap._followVehicle = !_flightMap._followVehicle
}
}
QGCButton {
id: centerMapButton
text: qsTr("Center map on Vehicle")
enabled: _activeVehicle && !followVehicleCheckBox.checked
property var activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
onClicked: {
_dropButtonsExclusiveGroup.current = null
_flightMap.center = activeVehicle.coordinate
}
}
}
}
}
//-- Map Type Control
DropButton {
id: mapTypeButton
dropDirection: dropRight
buttonImage: "/qmlimages/MapType.svg"
viewportMargins: ScreenTools.defaultFontPixelWidth / 2
exclusiveGroup: _dropButtonsExclusiveGroup
z: QGroundControl.zOrderWidgets
lightBorders: _lightWidgetBorders
dropDownComponent: Component {
Column {
spacing: ScreenTools.defaultFontPixelWidth
Row {
spacing: ScreenTools.defaultFontPixelWidth
Repeater {
model: QGroundControl.flightMapSettings.mapTypes
QGCButton {
checkable: true
checked: QGroundControl.flightMapSettings.mapType === text
text: modelData
width: clearButton.width
exclusiveGroup: _mapTypeButtonsExclusiveGroup
onClicked: {
QGroundControl.flightMapSettings.mapType = text
checked = true
_dropButtonsExclusiveGroup.current = null
}
}
}
}
QGCButton {
id: clearButton
text: qsTr("Clear Flight Trails")
enabled: QGroundControl.multiVehicleManager.activeVehicle
onClicked: {
QGroundControl.multiVehicleManager.activeVehicle.clearTrajectoryPoints()
_dropButtonsExclusiveGroup.current = null
}
}
}
}
}
//-- Zoom Map In
RoundButton {
id: mapZoomPlus
visible: !ScreenTools.isTinyScreen && _mainIsMap
buttonImage: "/qmlimages/ZoomPlus.svg"
exclusiveGroup: _dropButtonsExclusiveGroup
z: QGroundControl.zOrderWidgets
lightBorders: _lightWidgetBorders
onClicked: {
if(_flightMap)
_flightMap.zoomLevel += 0.5
checked = false
}
}
//-- Zoom Map Out
RoundButton {
id: mapZoomMinus
visible: !ScreenTools.isTinyScreen && _mainIsMap
buttonImage: "/qmlimages/ZoomMinus.svg"
exclusiveGroup: _dropButtonsExclusiveGroup
z: QGroundControl.zOrderWidgets
lightBorders: _lightWidgetBorders
onClicked: {
if(_flightMap)
_flightMap.zoomLevel -= 0.5
checked = false
}
}
}
//-- Guided mode buttons
Rectangle {
id: _guidedModeBar
......
Module QGroundControl.FlightDisplay
FlightDisplayView 1.0 FlightDisplayView.qml
FlightDisplayViewMap 1.0 FlightDisplayViewMap.qml
FlightDisplayViewVideo 1.0 FlightDisplayViewVideo.qml
FlightDisplayView 1.0 FlightDisplayView.qml
FlightDisplayViewMap 1.0 FlightDisplayViewMap.qml
FlightDisplayViewVideo 1.0 FlightDisplayViewVideo.qml
FlightDisplayViewWidgets 1.0 FlightDisplayViewWidgets.qml
......@@ -82,6 +82,14 @@ Map {
scaleText.text = text
}
function setVisibleRegion(region) {
// This works around a bug on Qt where if you set a visibleRegion and then the user moves or zooms the map
// and then you set the same visibleRegion the map will not move/scale appropriately since it thinks there
// is nothing to do.
_map.visibleRegion = QtPositioning.rectangle(QtPositioning.coordinate(0, 0), QtPositioning.coordinate(0, 0))
_map.visibleRegion = region
}
zoomLevel: 18
center: QGroundControl.lastKnownHomePosition
gesture.flickDeceleration: 3000
......
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
import QtQuick 2.4
import QtQuick.Controls 1.3
import QtQuick.Layouts 1.2
import QtPositioning 5.3
import QGroundControl 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.Controls 1.0
import QGroundControl.Palette 1.0
DropButton {
id: dropButton
dropDirection: dropRight
buttonImage: "/qmlimages/MapCenter.svg"
viewportMargins: ScreenTools.defaultFontPixelWidth / 2
lightBorders: map.isSatelliteMap
property var map
property rect mapFitViewport
property bool usePlannedHomePosition ///< true: planned home position used for calculations, false: vehicle home position use for calculations
property var geoFenceController
property var missionController
property var rallyPointController
property bool showMission: true
property bool showAllItems: true
property bool showFollowVehicle: false
property bool followVehicle: false
property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
function fitHomePosition() {
var homePosition = QtPositioning.coordinate()
var activeVehicle = QGroundControl.multiVehicleManager.activeVehicle
if (usePlannedHomePosition) {
homePosition = missionController.visualItems.get(0).coordinate
} else if (activeVehicle) {
homePosition = activeVehicle.homePosition
}
return homePosition
}
/// Normalize latitude to range: 0 to 180, S to N
function normalizeLat(lat) {
return lat + 90.0
}
/// Normalize longitude to range: 0 to 360, W to E
function normalizeLon(lon) {
return lon + 180.0
}
/// Fits the visible region of the map to inclues all of the specified coordinates. If no coordinates
/// are specified the map will center to fitHomePosition()
function fitMapViewportToAllCoordinates(coordList) {
if (coordList.length == 0) {
map.center = fitHomePosition()
return
}
// Create the normalized lat/lon corners for the coordinate bounding rect from the list of coordinates
var north = normalizeLat(coordList[0].latitude)
var south = north
var east = normalizeLon(coordList[0].longitude)
var west = east
for (var i=1; i<coordList.length; i++) {
var lat = normalizeLat(coordList[i].latitude)
var lon = normalizeLon(coordList[i].longitude)
north = Math.max(north, lat)
south = Math.min(south, lat)
east = Math.max(east, lon)
west = Math.min(west, lon)
}
// Expand the coordinate bounding rect to make room for the tools around the edge of the map
var latDegreesPerPixel = (north - south) / mapFitViewport.width
var lonDegreesPerPixel = (east - west) / mapFitViewport.height
north = Math.min(north + (mapFitViewport.y * latDegreesPerPixel), 180)
south = Math.max(south - ((map.height - mapFitViewport.bottom) * latDegreesPerPixel), 0)
west = Math.max(west - (mapFitViewport.x * lonDegreesPerPixel), 0)
east = Math.min(east + ((map.width - mapFitViewport.right) * lonDegreesPerPixel), 360)
// Fix the map region to the new bounding rect
var topLeftCoord = QtPositioning.coordinate(north - 90.0, west - 180.0)
var bottomRightCoord = QtPositioning.coordinate(south - 90.0, east - 180.0)
map.setVisibleRegion(QtPositioning.rectangle(topLeftCoord, bottomRightCoord))
}
function addMissionItemCoordsForFit(coordList) {
var homePosition = fitHomePosition()
if (homePosition.isValid) {
coordList.push(homePosition)
}
for (var i=1; i<missionController.visualItems.count; i++) {
var missionItem = missionController.visualItems.get(i)
if (missionItem.specifiesCoordinate && !missionItem.isStandaloneCoordinate) {
coordList.push(missionItem.coordinate)
}
}
}
function fitMapViewportToMissionItems() {
var coordList = [ ]
addMissionItemCoordsForFit(coordList)
fitMapViewportToAllCoordinates(coordList)
}
function addFenceItemCoordsForFit(coordList) {
var homePosition = fitHomePosition()
if (homePosition.isValid && geoFenceController.circleEnabled) {
var azimuthList = [ 0, 180, 90, 270 ]
for (var i=0; i<azimuthList.length; i++) {
var edgeCoordinate = homePosition.atDistanceAndAzimuth(geoFenceController.circleRadius, azimuthList[i])
coordList.push(edgeCoordinate)
}
}
if (geoFenceController.polygonEnabled && geoFenceController.polygon.count() > 2) {
for (var i=0; i<geoFenceController.polygon.count(); i++) {
coordList.push(geoFenceController.polygon.path[i])
}
}
}
function fitMapViewportToFenceItems() {
var coordList = [ ]
addFenceItemCoordsForFit(coordList)
fitMapViewportToAllCoordinates(coordList)
}
function addRallyItemCoordsForFit(coordList) {
for (var i=0; i<rallyPointController.points.count; i++) {
coordList.push(rallyPointController.points.get(i).coordinate)
}
}
function fitMapViewportToRallyItems() {
var coordList = [ ]
addRallyItemCoordsForFit(coordList)
fitMapViewportToAllCoordinates(coordList)
}
function fitMapViewportToAllItems() {
var coordList = [ ]
addMissionItemCoordsForFit(coordList)
addFenceItemCoordsForFit(coordList)
addRallyItemCoordsForFit(coordList)
fitMapViewportToAllCoordinates(coordList)
}
dropDownComponent: Component {
ColumnLayout {
spacing: ScreenTools.defaultFontPixelWidth * 0.5
QGCLabel { text: qsTr("Center map on:") }
QGCButton {
text: qsTr("Mission")
Layout.fillWidth: true
visible: showMission
enabled: !followVehicleCheckBox.checked
onClicked: {
dropButton.hideDropDown()
fitMapViewportToMissionItems()
}
}
QGCButton {
text: qsTr("All items")
Layout.fillWidth: true
visible: showAllItems
enabled: !followVehicleCheckBox.checked
onClicked: {
dropButton.hideDropDown()
fitMapViewportToAllItems()
}
}
QGCButton {
text: qsTr("Home")
Layout.fillWidth: true
enabled: !followVehicleCheckBox.checked
onClicked: {
dropButton.hideDropDown()
map.center = fitHomePosition()
}
}
QGCButton {
text: qsTr("Current Location")
Layout.fillWidth: true
enabled: mainWindow.gcsPosition.isValid && !followVehicleCheckBox.checked
onClicked: {
dropButton.hideDropDown()
map.center = mainWindow.gcsPosition
}
}
QGCButton {
text: qsTr("Vehicle")
Layout.fillWidth: true
enabled: _activeVehicle && _activeVehicle.latitude != 0 && _activeVehicle.longitude != 0 && !followVehicleCheckBox.checked
onClicked: {
dropButton.hideDropDown()
map.center = activeVehicle.coordinate
}
}
QGCCheckBox {
id: followVehicleCheckBox
text: qsTr("Follow Vehicle")
checked: followVehicle
visible: showFollowVehicle
onClicked: {
dropButton.hideDropDown()
dropButton.followVehicle = checked
}
}
} // Column
} // Component - dropDownComponent
} // DropButton
......@@ -5,6 +5,7 @@ FlightMap 1.0 FlightMap.qml
QGCVideoBackground 1.0 QGCVideoBackground.qml
# Widgets
CenterMapDropButton 1.0 CenterMapDropButton.qml
InstrumentSwipeView 1.0 InstrumentSwipeView.qml
MapScale 1.0 MapScale.qml
QGCArtificialHorizon 1.0 QGCArtificialHorizon.qml
......
This diff is collapsed.
import QtQuick 2.5
import QtQuick.Controls 1.2
/****************************************************************************
*
* (c) 2009-2016 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>
*
* QGroundControl is licensed according to the terms in the file
* COPYING.md in the root of the source code directory.
*
****************************************************************************/
import QtQuick 2.5
import QtQuick.Controls 1.2
import QGroundControl.Palette 1.0
import QGroundControl.ScreenTools 1.0
Rectangle
{
id: __mapButton
property var __qgcPal: QGCPalette { colorGroupEnabled: enabled }
property bool __showHighlight: (__pressed | __hovered | checked) && !__forceHoverOff
property bool __forceHoverOff: false
property int __lastGlobalMouseX: 0