8 changed files with 737 additions and 134 deletions
@ -0,0 +1,103 @@ |
|||||||
|
/**************************************************************************** |
||||||
|
* |
||||||
|
* (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 |
@ -0,0 +1,144 @@ |
|||||||
|
/**************************************************************************** |
||||||
|
* |
||||||
|
* (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 |
@ -0,0 +1,162 @@ |
|||||||
|
/**************************************************************************** |
||||||
|
* |
||||||
|
* (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 |
||||||
|
} |
@ -0,0 +1,183 @@ |
|||||||
|
/**************************************************************************** |
||||||
|
* |
||||||
|
* (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 |
||||||
|
} |
||||||
|
} |
Loading…
Reference in new issue