Commit 17e4a330 authored by Don Gagne's avatar Don Gagne

Use new ToolStrip control in Plan View

parent 526a2122
...@@ -94,6 +94,8 @@ ...@@ -94,6 +94,8 @@
<file alias="QGroundControl/Controls/SubMenuButton.qml">src/QmlControls/SubMenuButton.qml</file> <file alias="QGroundControl/Controls/SubMenuButton.qml">src/QmlControls/SubMenuButton.qml</file>
<file alias="QGroundControl/Controls/VehicleRotationCal.qml">src/QmlControls/VehicleRotationCal.qml</file> <file alias="QGroundControl/Controls/VehicleRotationCal.qml">src/QmlControls/VehicleRotationCal.qml</file>
<file alias="QGroundControl/Controls/VehicleSummaryRow.qml">src/QmlControls/VehicleSummaryRow.qml</file> <file alias="QGroundControl/Controls/VehicleSummaryRow.qml">src/QmlControls/VehicleSummaryRow.qml</file>
<file alias="QGroundControl/Controls/ToolStrip.qml">src/QmlControls/ToolStrip.qml</file>
<file alias="QGroundControl/Controls/DropPanel.qml">src/QmlControls/DropPanel.qml</file>
<file alias="QGroundControl/Controls/ViewWidget.qml">src/ViewWidgets/ViewWidget.qml</file> <file alias="QGroundControl/Controls/ViewWidget.qml">src/ViewWidgets/ViewWidget.qml</file>
<file alias="QGroundControl/FactControls/FactBitmask.qml">src/FactSystem/FactControls/FactBitmask.qml</file> <file alias="QGroundControl/FactControls/FactBitmask.qml">src/FactSystem/FactControls/FactBitmask.qml</file>
<file alias="QGroundControl/FactControls/FactCheckBox.qml">src/FactSystem/FactControls/FactCheckBox.qml</file> <file alias="QGroundControl/FactControls/FactCheckBox.qml">src/FactSystem/FactControls/FactCheckBox.qml</file>
...@@ -111,6 +113,8 @@ ...@@ -111,6 +113,8 @@
<file alias="QGroundControl/FlightDisplay/MultiVehicleList.qml">src/FlightDisplay/MultiVehicleList.qml</file> <file alias="QGroundControl/FlightDisplay/MultiVehicleList.qml">src/FlightDisplay/MultiVehicleList.qml</file>
<file alias="QGroundControl/FlightDisplay/qmldir">src/FlightDisplay/qmldir</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/CenterMapDropButton.qml">src/FlightMap/Widgets/CenterMapDropButton.qml</file>
<file alias="QGroundControl/FlightMap/CenterMapDropPanel.qml">src/FlightMap/Widgets/CenterMapDropPanel.qml</file>
<file alias="QGroundControl/FlightMap/MapFitFunctions.qml">src/FlightMap/Widgets/MapFitFunctions.qml</file>
<file alias="QGroundControl/FlightMap/FlightMap.qml">src/FlightMap/FlightMap.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/InstrumentSwipeView.qml">src/FlightMap/Widgets/InstrumentSwipeView.qml</file>
<file alias="QGroundControl/FlightMap/MapScale.qml">src/FlightMap/MapScale.qml</file> <file alias="QGroundControl/FlightMap/MapScale.qml">src/FlightMap/MapScale.qml</file>
......
/****************************************************************************
*
* (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
ColumnLayout {
id: root
spacing: ScreenTools.defaultFontPixelWidth * 0.5
property var map
property var fitFunctions
property bool showMission: true
property bool showAllItems: true
property bool showFollowVehicle: false
property bool followVehicle: false
property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
QGCLabel { text: qsTr("Center map on:") }
QGCButton {
text: qsTr("Mission")
Layout.fillWidth: true
visible: showMission
enabled: !followVehicleCheckBox.checked
onClicked: {
dropPanel.hide()
fitFunctions.fitMapViewportToMissionItems()
}
}
QGCButton {
text: qsTr("All items")
Layout.fillWidth: true
visible: showAllItems
enabled: !followVehicleCheckBox.checked
onClicked: {
dropPanel.hide()
fitFunctions.fitMapViewportToAllItems()
}
}
QGCButton {
text: qsTr("Home")
Layout.fillWidth: true
enabled: !followVehicleCheckBox.checked
onClicked: {
dropPanel.hide()
map.center = fitFunctions.fitHomePosition()
}
}
QGCButton {
text: qsTr("Current Location")
Layout.fillWidth: true
enabled: mainWindow.gcsPosition.isValid && !followVehicleCheckBox.checked
onClicked: {
dropPanel.hide()
map.center = mainWindow.gcsPosition
}
}
QGCButton {
text: qsTr("Vehicle")
Layout.fillWidth: true
enabled: _activeVehicle && _activeVehicle.latitude != 0 && _activeVehicle.longitude != 0 && !followVehicleCheckBox.checked
onClicked: {
dropPanel.hide()
map.center = activeVehicle.coordinate
}
}
QGCCheckBox {
id: followVehicleCheckBox
text: qsTr("Follow Vehicle")
checked: followVehicle
visible: showFollowVehicle
onClicked: {
dropPanel.hide()
_root.followVehicle = checked
}
}
} // Column
/****************************************************************************
*
* (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 QtPositioning 5.3
import QGroundControl 1.0
/// Set of functions for fitting the map viewpoer to a specific constraint
Item {
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 mapGeoFenceController
property var mapMissionController
property var mapRallyPointController
property var _activeVehicle: QGroundControl.multiVehicleManager.activeVehicle
function fitHomePosition() {
var homePosition = QtPositioning.coordinate()
var activeVehicle = QGroundControl.multiVehicleManager.activeVehicle
if (usePlannedHomePosition) {
homePosition = mapMissionController.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<mapMissionController.visualItems.count; i++) {
var missionItem = mapMissionController.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 && mapGeoFenceController.circleEnabled) {
var azimuthList = [ 0, 180, 90, 270 ]
for (var i=0; i<azimuthList.length; i++) {
var edgeCoordinate = homePosition.atDistanceAndAzimuth(mapGeoFenceController.circleRadius, azimuthList[i])
coordList.push(edgeCoordinate)
}
}
if (mapGeoFenceController.polygonEnabled && mapGeoFenceController.polygon.count() > 2) {
for (var i=0; i<mapGeoFenceController.polygon.count(); i++) {
coordList.push(mapGeoFenceController.polygon.path[i])
}
}
}
function fitMapViewportToFenceItems() {
var coordList = [ ]
addFenceItemCoordsForFit(coordList)
fitMapViewportToAllCoordinates(coordList)
}
function addRallyItemCoordsForFit(coordList) {
for (var i=0; i<mapRallyPointController.points.count; i++) {
coordList.push(mapRallyPointController.points.get(i).coordinate)
}
}
function fitMapViewportToRallyItems() {
var coordList = [ ]
addRallyItemCoordsForFit(coordList)
fitMapViewportToAllCoordinates(coordList)
}
function fitMapViewportToAllItems() {
var coordList = [ ]
addMissionItemCoordsForFit(coordList)
addFenceItemCoordsForFit(coordList)
addRallyItemCoordsForFit(coordList)
fitMapViewportToAllCoordinates(coordList)
}
} // Item
Module QGroundControl.FlightMap Module QGroundControl.FlightMap
# Main view controls # Main view controls
FlightMap 1.0 FlightMap.qml FlightMap 1.0 FlightMap.qml
QGCVideoBackground 1.0 QGCVideoBackground.qml QGCVideoBackground 1.0 QGCVideoBackground.qml
# Widgets # Widgets
CenterMapDropButton 1.0 CenterMapDropButton.qml CenterMapDropButton 1.0 CenterMapDropButton.qml
CenterMapDropPanel 1.0 CenterMapDropPanel.qml
InstrumentSwipeView 1.0 InstrumentSwipeView.qml InstrumentSwipeView 1.0 InstrumentSwipeView.qml
MapFitFunctions 1.0 MapFitFunctions.qml
MapScale 1.0 MapScale.qml MapScale 1.0 MapScale.qml
QGCArtificialHorizon 1.0 QGCArtificialHorizon.qml QGCArtificialHorizon 1.0 QGCArtificialHorizon.qml
QGCAttitudeHUD 1.0 QGCAttitudeHUD.qml QGCAttitudeHUD 1.0 QGCAttitudeHUD.qml
......
This diff is collapsed.
/****************************************************************************
*
* (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.2
import QtQuick.Controls.Styles 1.2
import QGroundControl 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.Palette 1.0
Item {
id: _root
z: QGroundControl.zOrderWidgets
visible: false
signal clicked()
property real radius: ScreenTools.isMobile ? ScreenTools.defaultFontPixelHeight * 1.75 : ScreenTools.defaultFontPixelHeight * 1.25
property real viewportMargins: 0
property real topMargin: parent.height - ScreenTools.availableHeight
property var toolStrip
width: radius * 2
height: radius * 2
// Should be an enum but that get's into the whole problem of creating a singleton which isn't worth the effort
readonly property int dropLeft: 1
readonly property int dropRight: 2
readonly property int dropUp: 3
readonly property int dropDown: 4
readonly property real _arrowBaseWidth: radius // Width of long side of arrow
readonly property real _arrowPointHeight: radius * 0.666 // Height is long side to point
readonly property real _dropCornerRadius: ScreenTools.defaultFontPixelWidth * 0.5
readonly property real _dropCornerRadiusX2: _dropCornerRadius * 2
readonly property real _dropMargin: _dropCornerRadius
readonly property real _dropMarginX2: _dropMargin * 2
property var _dropEdgeTopPoint
property real _dropEdgeHeight
property alias _dropDownComponent: dropDownLoader.sourceComponent
property real _viewportMaxLeft: -x + viewportMargins
property real _viewportMaxRight: parent.width - (viewportMargins * 2) - x
property real _viewportMaxTop: -y + viewportMargins + topMargin
property real _viewportMaxBottom: parent.height - (viewportMargins * 2) - y
function show(panelEdgeTopPoint, panelEdgeHeight, panelComponent) {
_dropEdgeTopPoint = panelEdgeTopPoint
_dropEdgeHeight = panelEdgeHeight
_dropDownComponent = panelComponent
_calcPositions()
visible = true
}
function hide() {
if (visible) {
visible = false
_dropDownComponent = undefined
toolStrip.uncheckAll()
}
}
function _calcPositions() {
var dropComponentWidth = dropDownLoader.item.width
var dropComponentHeight = dropDownLoader.item.height
var dropRectWidth = dropComponentWidth + _dropMarginX2
var dropRectHeight = dropComponentHeight + _dropMarginX2
dropItemHolderRect.width = dropRectWidth
dropItemHolderRect.height = dropRectHeight
dropDownItem.width = dropComponentWidth + _dropMarginX2
dropDownItem.height = dropComponentHeight + _dropMarginX2
dropDownItem.width += _arrowPointHeight
dropDownItem.y = _dropEdgeTopPoint.y -(dropDownItem.height / 2) + radius
dropItemHolderRect.y = 0
dropDownItem.x = _dropEdgeTopPoint.x + _dropMargin
dropItemHolderRect.x = _arrowPointHeight
// Validate that dropdown is within viewport
dropDownItem.y = Math.max(dropDownItem.y, _viewportMaxTop)
dropDownItem.y = Math.min(dropDownItem.y + dropDownItem.height, _viewportMaxBottom) - dropDownItem.height
// Arrow points
arrowCanvas.arrowPoint.y = (_dropEdgeTopPoint.y + radius) - dropDownItem.y
arrowCanvas.arrowPoint.x = 0
arrowCanvas.arrowBase1.x = _arrowPointHeight
arrowCanvas.arrowBase1.y = arrowCanvas.arrowPoint.y - (_arrowBaseWidth / 2)
arrowCanvas.arrowBase2.x = arrowCanvas.arrowBase1.x
arrowCanvas.arrowBase2.y = arrowCanvas.arrowBase1.y + _arrowBaseWidth
arrowCanvas.requestPaint()
} // function - _calcPositions
QGCPalette { id: qgcPal }
/*
MouseArea {
x: _viewportMaxLeft
y: _viewportMaxTop
width: _viewportMaxRight -_viewportMaxLeft
height: _viewportMaxBottom - _viewportMaxTop
visible: checked
onClicked: {
checked = false
_root.clicked()
}
}*/
Item {
id: dropDownItem
Canvas {
id: arrowCanvas
anchors.fill: parent
property var arrowPoint: Qt.point(0, 0)
property var arrowBase1: Qt.point(0, 0)
property var arrowBase2: Qt.point(0, 0)
onPaint: {
var context = getContext("2d")
context.reset()
context.beginPath()
context.moveTo(dropItemHolderRect.x, dropItemHolderRect.y)
context.lineTo(dropItemHolderRect.x + dropItemHolderRect.width, dropItemHolderRect.y)
context.lineTo(dropItemHolderRect.x + dropItemHolderRect.width, dropItemHolderRect.y + dropItemHolderRect.height)
context.lineTo(dropItemHolderRect.x, dropItemHolderRect.y + dropItemHolderRect.height)
context.lineTo(arrowBase2.x, arrowBase2.y)
context.lineTo(arrowPoint.x, arrowPoint.y)
context.lineTo(arrowBase1.x, arrowBase1.y)
context.lineTo(dropItemHolderRect.x, dropItemHolderRect.y)
context.closePath()
context.fillStyle = qgcPal.windowShade
context.fill()
}
} // Canvas - arrowCanvas
Item {
id: dropItemHolderRect
Loader {
id: dropDownLoader
x: _dropMargin
y: _dropMargin
property var dropPanel: _root
}
}
} // Item - dropDownItem
}
...@@ -4,6 +4,7 @@ AnalyzePage 1.0 AnalyzePage.qml ...@@ -4,6 +4,7 @@ AnalyzePage 1.0 AnalyzePage.qml
AppMessages 1.0 AppMessages.qml AppMessages 1.0 AppMessages.qml
ClickableColor 1.0 ClickableColor.qml ClickableColor 1.0 ClickableColor.qml
DropButton 1.0 DropButton.qml DropButton 1.0 DropButton.qml
DropPanel 1.0 DropPanel.qml
ExclusiveGroupItem 1.0 ExclusiveGroupItem.qml ExclusiveGroupItem 1.0 ExclusiveGroupItem.qml
FactSliderPanel 1.0 FactSliderPanel.qml FactSliderPanel 1.0 FactSliderPanel.qml
FlightModeDropdown 1.0 FlightModeDropdown.qml FlightModeDropdown 1.0 FlightModeDropdown.qml
...@@ -49,6 +50,7 @@ SetupPage 1.0 SetupPage.qml ...@@ -49,6 +50,7 @@ SetupPage 1.0 SetupPage.qml
SignalStrength 1.0 SignalStrength.qml SignalStrength 1.0 SignalStrength.qml
SliderSwitch 1.0 SliderSwitch.qml SliderSwitch 1.0 SliderSwitch.qml
SubMenuButton 1.0 SubMenuButton.qml SubMenuButton 1.0 SubMenuButton.qml
ToolStrip 1.0 ToolStrip.qml
VehicleRotationCal 1.0 VehicleRotationCal.qml VehicleRotationCal 1.0 VehicleRotationCal.qml
VehicleSummaryRow 1.0 VehicleSummaryRow.qml VehicleSummaryRow 1.0 VehicleSummaryRow.qml
ViewWidget 1.0 ViewWidget.qml ViewWidget 1.0 ViewWidget.qml
......
/****************************************************************************
*
* (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.2
import QGroundControl.ScreenTools 1.0
import QGroundControl.Palette 1.0
Rectangle {
id: _root
color: qgcPal.window
width: ScreenTools.defaultFontPixelWidth * 6
height: buttonStripColumn.height + (buttonStripColumn.anchors.margins * 2)
radius: _radius
property string title: "Title"
property alias model: repeater.model
property var showAlternateIcon
property var rotateImage
property var buttonEnabled
signal clicked(int index, bool checked)
readonly property real _radius: ScreenTools.defaultFontPixelWidth / 2
readonly property real _margin: ScreenTools.defaultFontPixelWidth / 2
readonly property real _buttonSpacing: ScreenTools.defaultFontPixelWidth
ExclusiveGroup {
id: dropButtonsExclusiveGroup
}
function uncheckAll() {
dropButtonsExclusiveGroup.current = null
// Signal all toggles as off
for (var i=0; i<model.length; i++) {
if (model[i].toggleButton === true) {
clicked(index, false)
}
}
}
MouseArea {
x: -_root.x
y: -_root.y
width: _root.parent.width
height: _root.parent.height
visible: dropPanel.visible
onClicked: dropPanel.hide()
}
Column {
id: buttonStripColumn
anchors.margins: ScreenTools.defaultFontPixelWidth / 2
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
QGCLabel {
anchors.horizontalCenter: parent.horizontalCenter
text: title
}
Item { width: 1; height: _buttonSpacing }
Rectangle {
anchors.left: parent.left
anchors.right: parent.right
height: 1
color: qgcPal.text
}
Repeater {
id: repeater
delegate: Column {
id: buttonColumn
width: buttonStripColumn.width
property bool checked: false
property ExclusiveGroup exclusiveGroup: dropButtonsExclusiveGroup
property var _iconSource: modelData.iconSource
property var _alternateIconSource: modelData.alternateIconSource
property var _source: _root.showAlternateIcon[index] ? _alternateIconSource : _iconSource
property bool rotateImage: _root.rotateImage[index]
onExclusiveGroupChanged: {
if (exclusiveGroup) {
exclusiveGroup.bindCheckable(buttonColumn)
}
}
onRotateImageChanged: {
if (rotateImage) {
imageRotation.running = true
} else {
imageRotation.running = false
button.rotation = 0
}
}
Item { width: 1; height: _buttonSpacing }
Rectangle {
anchors.left: parent.left
anchors.right: parent.right
height: width
color: checked ? qgcPal.buttonHighlight : qgcPal.button
QGCColoredImage {
id: button
anchors.fill: parent
source: _source
sourceSize.height: parent.height
fillMode: Image.PreserveAspectFit
mipmap: true
smooth: true
color: checked ? qgcPal.buttonHighlightText : qgcPal.buttonText
RotationAnimation on rotation {
id: imageRotation
loops: Animation.Infinite
from: 0
to: 360
duration: 500
running: false
}
}
MouseArea {
anchors.left: parent.left
anchors.right: parent.right
anchors.top: parent.top
height: parent.height + buttonLabel.height + buttonColumn.spacing
visible: _root.buttonEnabled[index]
onClicked: {
if (modelData.dropPanelComponent === undefined) {
dropPanel.hide()
if (modelData.toggle === true) {
checked = !checked
} else {
// dropPanel.hide above will close panel, but we need to do this to clear toggles
uncheckAll()
}
_root.clicked(index, checked)
} else {
if (checked) {
dropPanel.hide() // hide affects checked, so this needs to be duplicated inside not outside if
} else {
dropPanel.hide() // hide affects checked, so this needs to be duplicated inside not outside if
checked = true
var panelEdgeTopPoint = mapToItem(_root, width, 0)
dropPanel.show(panelEdgeTopPoint, height, modelData.dropPanelComponent)
}
}
}
}
}
QGCLabel {
id: buttonLabel
anchors.horizontalCenter: parent.horizontalCenter
font.pointSize: ScreenTools.smallFontPointSize
text: modelData.name
}
}
}
}
DropPanel {
id: dropPanel
toolStrip: _root
}
}
Markdown is supported
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