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

Use new ToolStrip control in Plan View

parent 526a2122
......@@ -94,6 +94,8 @@
<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/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/FactControls/FactBitmask.qml">src/FactSystem/FactControls/FactBitmask.qml</file>
<file alias="QGroundControl/FactControls/FactCheckBox.qml">src/FactSystem/FactControls/FactCheckBox.qml</file>
......@@ -111,6 +113,8 @@
<file alias="QGroundControl/FlightDisplay/MultiVehicleList.qml">src/FlightDisplay/MultiVehicleList.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/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/InstrumentSwipeView.qml">src/FlightMap/Widgets/InstrumentSwipeView.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
# Main view controls
FlightMap 1.0 FlightMap.qml
QGCVideoBackground 1.0 QGCVideoBackground.qml
FlightMap 1.0 FlightMap.qml
QGCVideoBackground 1.0 QGCVideoBackground.qml
# Widgets
CenterMapDropButton 1.0 CenterMapDropButton.qml
CenterMapDropPanel 1.0 CenterMapDropPanel.qml
InstrumentSwipeView 1.0 InstrumentSwipeView.qml
MapFitFunctions 1.0 MapFitFunctions.qml
MapScale 1.0 MapScale.qml
QGCArtificialHorizon 1.0 QGCArtificialHorizon.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
AppMessages 1.0 AppMessages.qml
ClickableColor 1.0 ClickableColor.qml
DropButton 1.0 DropButton.qml
DropPanel 1.0 DropPanel.qml
ExclusiveGroupItem 1.0 ExclusiveGroupItem.qml
FactSliderPanel 1.0 FactSliderPanel.qml
FlightModeDropdown 1.0 FlightModeDropdown.qml
......@@ -49,6 +50,7 @@ SetupPage 1.0 SetupPage.qml
SignalStrength 1.0 SignalStrength.qml
SliderSwitch 1.0 SliderSwitch.qml
SubMenuButton 1.0 SubMenuButton.qml
ToolStrip 1.0 ToolStrip.qml
VehicleRotationCal 1.0 VehicleRotationCal.qml
VehicleSummaryRow 1.0 VehicleSummaryRow.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