diff --git a/qgroundcontrol.qrc b/qgroundcontrol.qrc index 34396fe3381a42bc3984c2e630b007e6af047dfe..545f877164c8bb935b8ec2634ea861931d9c5b02 100644 --- a/qgroundcontrol.qrc +++ b/qgroundcontrol.qrc @@ -101,6 +101,7 @@ src/QmlControls/MissionItemIndexLabel.qml src/QmlControls/MissionItemSummary.qml src/QmlControls/MissionItemEditor.qml + src/QmlControls/DropButton.qml src/VehicleSetup/SetupView.qml diff --git a/src/FlightMap/FlightMap.qml b/src/FlightMap/FlightMap.qml index 1886f499f907dc2c826cafc86a09aa2043ec72d9..a764bb8e72e33296b237476db01a873a20152c0e 100644 --- a/src/FlightMap/FlightMap.qml +++ b/src/FlightMap/FlightMap.qml @@ -107,6 +107,8 @@ Map { anchors.right: parent.right anchors.bottom: parent.bottom spacing: ScreenTools.defaultFontPixelWidth / 2 + z: 1000 // Must be on top for clicking + visible: !ScreenTools.isMobile Row { layoutDirection: Qt.RightToLeft diff --git a/src/MissionEditor/MissionEditor.qml b/src/MissionEditor/MissionEditor.qml index d52ecdbfc3a23ade54bb984abc550a1ec65aefee..5ac9325dbf77e8b73338facf29fd57f89ec1888e 100644 --- a/src/MissionEditor/MissionEditor.qml +++ b/src/MissionEditor/MissionEditor.qml @@ -77,7 +77,7 @@ QGCView { longitude: _homePositionCoordinate.longitude QGCLabel { - anchors.right: parent.right + anchors.bottom: parent.bottom text: "WIP: Danger, do not fly with this!"; font.pixelSize: ScreenTools.largeFontPixelSize } @@ -98,9 +98,74 @@ QGCView { } } + DropButton { + id: centerMapButton + anchors.rightMargin: ScreenTools.defaultFontPixelHeight + anchors.right: mapTypeButton.left + anchors.top: mapTypeButton.top + dropDirection: dropDown + label: "C" + viewportMargins: ScreenTools.defaultFontPixelWidth / 2 + + dropDownComponent: Component { + Row { + spacing: ScreenTools.defaultFontPixelWidth + + QGCButton { + text: "Home" + + onClicked: centerMapButton.hideDropDown() + } + + QGCButton { + text: "All Items" + + onClicked: centerMapButton.hideDropDown() + } + } + } + } + + DropButton { + id: mapTypeButton + anchors.margins: ScreenTools.defaultFontPixelHeight + anchors.top: parent.top + anchors.right: parent.right + dropDirection: dropDown + label: "M" + viewportMargins: ScreenTools.defaultFontPixelWidth / 2 + + dropDownComponent: Component { + Row { + spacing: ScreenTools.defaultFontPixelWidth + + QGCButton { + text: "Street" + + onClicked: mapTypeButton.hideDropDown() + } + + QGCButton { + text: "Satellite" + + onClicked: mapTypeButton.hideDropDown() + } + + QGCButton { + text: "Hybrid" + + onClicked: mapTypeButton.hideDropDown() + } + } + } + } + MissionItemIndicator { label: "H" + isCurrentItem: _showHomePositionManager coordinate: _homePositionCoordinate + + onClicked: _showHomePositionManager = true } // Add the mission items to the map @@ -110,10 +175,13 @@ QGCView { delegate: MissionItemIndicator { label: object.sequenceNumber - isCurrentItem: object.isCurrentItem + isCurrentItem: !_showHomePositionManager && object.isCurrentItem coordinate: object.coordinate - onClicked: setCurrentItem(object.sequenceNumber) + onClicked: { + _showHomePositionManager = false + setCurrentItem(object.sequenceNumber) + } Component.onCompleted: console.log("Indicator", object.coordinate) } diff --git a/src/QmlControls/DropButton.qml b/src/QmlControls/DropButton.qml new file mode 100644 index 0000000000000000000000000000000000000000..7a2acd1858ebdbe6f02ea87df54264107f5e12db --- /dev/null +++ b/src/QmlControls/DropButton.qml @@ -0,0 +1,230 @@ +import QtQuick 2.2 +import QtQuick.Controls 1.2 +import QtQuick.Controls.Styles 1.2 + +import QGroundControl.ScreenTools 1.0 +import QGroundControl.Palette 1.0 + +Item { + id: _root + + property alias label: buttonLabel.text + property alias radius: button.radius + property int dropDirection: dropDown + property alias dropDownComponent: dropDownLoader.sourceComponent + property real viewportMargins: 0 + + 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 + + function hideDropDown() { + _showDropDown = false + } + + readonly property real _arrowBaseWidth: (radius * 2) / 2 // Width of long side of arrow + readonly property real _arrowPointHeight: (radius * 2) / 3 // Height is long side to point + readonly property real _dropCornerRadius: ScreenTools.defaultFontPixelWidth / 2 + readonly property real _dropCornerRadiusX2: _dropCornerRadius * 2 + readonly property real _dropMargin: _dropCornerRadius + readonly property real _dropMarginX2: _dropMargin * 2 + + property real _viewportMaxLeft: -x + viewportMargins + property real _viewportMaxRight: parent.width - (viewportMargins * 2) - x + property real _viewportMaxTop: -y + viewportMargins + property real _viewportMaxBottom: parent.height - (viewportMargins * 2) - y + + property bool _showDropDown: false + + Component.onCompleted: _calcPositions() + + 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 + + if (dropDirection == dropUp || dropDirection == dropDown) { + dropDownItem.height += _arrowPointHeight + + dropDownItem.x = -(dropDownItem.width / 2) + radius + + dropItemHolderRect.x = 0 + + if (dropDirection == dropUp) { + dropDownItem.y = -(dropDownItem.height + _dropMargin) + + dropItemHolderRect.y = 0 + } else { + dropDownItem.y = button.height + _dropMargin + + dropItemHolderRect.y = _arrowPointHeight + } + + // Validate that dropdown is within viewport + dropDownItem.x = Math.max(dropDownItem.x, _viewportMaxLeft) + dropDownItem.x = Math.min(dropDownItem.x + dropDownItem.width, _viewportMaxRight) - dropDownItem.width + + // Arrow points + arrowCanvas.arrowPoint.x = (button.x + radius) - dropDownItem.x + if (dropDirection == dropUp) { + arrowCanvas.arrowPoint.y = dropDownItem.height + arrowCanvas.arrowBase1.x = arrowCanvas.arrowPoint.x - (_arrowBaseWidth / 2) + arrowCanvas.arrowBase1.y = arrowCanvas.arrowPoint.y - _arrowPointHeight + arrowCanvas.arrowBase2.x = arrowCanvas.arrowBase1.x + _arrowBaseWidth + arrowCanvas.arrowBase2.y = arrowCanvas.arrowBase1.y + } else { + arrowCanvas.arrowPoint.y = 0 + arrowCanvas.arrowBase1.x = arrowCanvas.arrowPoint.x + (_arrowBaseWidth / 2) + arrowCanvas.arrowBase1.y = _arrowPointHeight + arrowCanvas.arrowBase2.x = arrowCanvas.arrowBase1.x - _arrowBaseWidth + arrowCanvas.arrowBase2.y = arrowCanvas.arrowBase1.y + } + } else { + dropDownItem.width += _arrowPointHeight + + dropDownItem.y = -(dropDownItem.height / 2) + radius + + dropItemHolderRect.y = 0 + + if (dropDirection == dropLeft) { + dropDownItem.x = dropDownItem.width + _dropMargin + + dropItemHolderRect.x = 0 + } else { + dropDownItem.x = button.width + _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 = (button.y + radius) - dropDownItem.y + if (dropDirection == dropLeft) { + arrowCanvas.arrowPoint.x = dropDownItem.width + arrowCanvas.arrowBase1.x = arrowCanvas.arrowPoint.x - _arrowPointHeight + arrowCanvas.arrowBase1.y = arrowCanvas.arrowPoint.y - (_arrowBaseWidth / 2) + arrowCanvas.arrowBase2.x = arrowCanvas.arrowBase1.x + arrowCanvas.arrowBase2.y = arrowCanvas.arrowBase1.y + _arrowBaseWidth + } else { + 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: _showDropDown + + onClicked: _showDropDown = false + } + + // Button + Rectangle { + id: button + anchors.fill: parent + radius: (ScreenTools.defaultFontPixelHeight * 3) / 2 + color: qgcPal.button + opacity: _showDropDown ? 1.0 : 0.75 + + QGCLabel { + id: buttonLabel + anchors.fill: parent + horizontalAlignment: Text.AlignHCenter + verticalAlignment: Text.AlignVCenter + color: "white" + } + + MouseArea { + anchors.fill: parent + + onClicked: _showDropDown = !_showDropDown + } + } // Rectangle - button + + Item { + id: dropDownItem + visible: _showDropDown + + 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) + if (dropDirection == dropDown) { + context.lineTo(arrowBase2.x, arrowBase2.y) + context.lineTo(arrowPoint.x, arrowPoint.y) + context.lineTo(arrowBase1.x, arrowBase1.y) + } + context.lineTo(dropItemHolderRect.x + dropItemHolderRect.width, dropItemHolderRect.y) + if (dropDirection == dropLeft) { + context.lineTo(arrowBase2.x, arrowBase2.y) + context.lineTo(arrowPoint.x, arrowPoint.y) + context.lineTo(arrowBase1.x, arrowBase1.y) + } + context.lineTo(dropItemHolderRect.x + dropItemHolderRect.width, dropItemHolderRect.y + dropItemHolderRect.height) + if (dropDirection == dropUp) { + context.lineTo(arrowBase2.x, arrowBase2.y) + context.lineTo(arrowPoint.x, arrowPoint.y) + context.lineTo(arrowBase1.x, arrowBase1.y) + } + context.lineTo(dropItemHolderRect.x, dropItemHolderRect.y + dropItemHolderRect.height) + if (dropDirection == dropRight) { + 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.button + context.fill() + } + } // Canvas - arrowCanvas + + Item { + id: dropItemHolderRect + //color: qgcPal.button + //radius: _dropCornerRadius + + Loader { + id: dropDownLoader + x: _dropMargin + y: _dropMargin + } + } + } // Item - dropDownItem +} diff --git a/src/QmlControls/QGroundControl.Controls.qmldir b/src/QmlControls/QGroundControl.Controls.qmldir index 62674c353b4c63ca22a9d628fe133080831d8eb8..cc9b94af863eb80dbf383a5ef39b88434e96cf10 100644 --- a/src/QmlControls/QGroundControl.Controls.qmldir +++ b/src/QmlControls/QGroundControl.Controls.qmldir @@ -12,6 +12,7 @@ QGCMovableItem 1.0 QGCMovableItem.qml SubMenuButton 1.0 SubMenuButton.qml IndicatorButton 1.0 IndicatorButton.qml +DropButton 1.0 DropButton.qml VehicleRotationCal 1.0 VehicleRotationCal.qml VehicleSummaryRow 1.0 VehicleSummaryRow.qml ViewWidget 1.0 ViewWidget.qml