Browse Source

Merge pull request #7731 from mavlink/pairingTweaks

Pairing UI Tweaks
QGC4.4
Gus Grubba 6 years ago committed by GitHub
parent
commit
90a7c22b16
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 7
      custom-example/custom.qrc
  2. 23
      custom-example/res/Images/PairingButton.svg
  3. 44
      custom-example/res/Images/PairingConnected.svg
  4. 11
      custom-example/res/Images/PairingError.svg
  5. 31
      custom-example/res/Images/PairingIcon.svg
  6. 0
      custom-example/res/Images/PairingIconLight.svg
  7. 40
      custom-example/res/MainToolbar/CustomMainToolBarIndicators.qml
  8. 443
      custom-example/res/PairingIndicator.qml
  9. 2
      custom-example/src/FirmwarePlugin/CustomFirmwarePlugin.cc
  10. 8
      qgcimages.qrc
  11. 1
      qgroundcontrol.qrc
  12. 23
      src/PairingManager/Images/PairingIcon.svg
  13. 49
      src/PairingManager/PairingManager.cc
  14. 92
      src/PairingManager/PairingManager.h
  15. 4
      src/ui/preferences/GeneralSettings.qml

7
custom-example/custom.qrc

@ -10,6 +10,7 @@
<file alias="CustomModeIndicator.qml">res/MainToolbar/CustomModeIndicator.qml</file> <file alias="CustomModeIndicator.qml">res/MainToolbar/CustomModeIndicator.qml</file>
<file alias="CustomMultiVehicleSelector.qml">res/MainToolbar/CustomMultiVehicleSelector.qml</file> <file alias="CustomMultiVehicleSelector.qml">res/MainToolbar/CustomMultiVehicleSelector.qml</file>
<file alias="CustomRCRSSIIndicator.qml">res/MainToolbar/CustomRCRSSIIndicator.qml</file> <file alias="CustomRCRSSIIndicator.qml">res/MainToolbar/CustomRCRSSIIndicator.qml</file>
<file alias="PairingIndicator.qml">res/PairingIndicator.qml</file>
<file alias="PreFlightCheckList.qml">res/PreFlightCheckList.qml</file> <file alias="PreFlightCheckList.qml">res/PreFlightCheckList.qml</file>
</qresource> </qresource>
<qresource prefix="custom/img"> <qresource prefix="custom/img">
@ -25,12 +26,16 @@
<file alias="compass_pointer.svg">res/Images/compass_pointer.svg</file> <file alias="compass_pointer.svg">res/Images/compass_pointer.svg</file>
<file alias="distance.svg">res/Images/distance.svg</file> <file alias="distance.svg">res/Images/distance.svg</file>
<file alias="gimbal_icon.svg">res/Images/gimbal_icon.svg</file> <file alias="gimbal_icon.svg">res/Images/gimbal_icon.svg</file>
<file alias="gimbal_position.svg">res/Images/gimbal_position.svg</file>
<file alias="gimbal_pitch_indoors.svg">res/Images/gimbal_pitch_indoors.svg</file> <file alias="gimbal_pitch_indoors.svg">res/Images/gimbal_pitch_indoors.svg</file>
<file alias="gimbal_pitch_outdoors.svg">res/Images/gimbal_pitch_outdoors.svg</file> <file alias="gimbal_pitch_outdoors.svg">res/Images/gimbal_pitch_outdoors.svg</file>
<file alias="gimbal_position.svg">res/Images/gimbal_position.svg</file>
<file alias="horizontal_speed.svg">res/Images/horizontal_speed.svg</file> <file alias="horizontal_speed.svg">res/Images/horizontal_speed.svg</file>
<file alias="microSD.svg">res/Images/microSD.svg</file> <file alias="microSD.svg">res/Images/microSD.svg</file>
<file alias="odometer.svg">res/Images/odometer.svg</file> <file alias="odometer.svg">res/Images/odometer.svg</file>
<file alias="PairingButton.svg">res/Images/PairingButton.svg</file>
<file alias="PairingConnected.svg">res/Images/PairingConnected.svg</file>
<file alias="PairingError.svg">res/Images/PairingError.svg</file>
<file alias="PairingIcon.svg">res/Images/PairingIcon.svg</file>
<file alias="thermal-brightness.svg">res/Images/thermal-brightness.svg</file> <file alias="thermal-brightness.svg">res/Images/thermal-brightness.svg</file>
<file alias="thermal-palette.svg">res/Images/thermal-palette.svg</file> <file alias="thermal-palette.svg">res/Images/thermal-palette.svg</file>
<file alias="thermal-pip.svg">res/Images/thermal-pip.svg</file> <file alias="thermal-pip.svg">res/Images/thermal-pip.svg</file>

23
custom-example/res/Images/PairingButton.svg

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.6, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 288 288" style="enable-background:new 0 0 288 288;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
</style>
<path class="st0" d="M106.783,143.429c-1.327-5.063-2.711-10.125-4.095-15.256c-29.464-2.025-52.834-26.495-52.834-56.465
c0-31.299,25.438-56.736,56.736-56.736s56.647,25.438,56.647,56.736c0,17.247-7.752,32.684-19.902,43.067
c0.675,1.744,1.373,3.499,2.048,5.209c1.496,3.792,2.576,6.345,3.814,9.394c17.641-13.062,29.116-34.032,29.116-57.669
c-0.011-39.614-32.108-71.71-71.722-71.71s-71.71,32.099-71.71,71.71c0,39.614,32.108,71.71,71.71,71.71
c0.068,0.011,0.124,0.011,0.191,0.011L106.783,143.429z"/>
<path class="st0" d="M231.879,162.801c-13.321-4.534-33.3-7.223-50.043-8.562c-16.932-1.35-30.42-1.485-30.42-1.485h-1.395
l-0.461-1.215c0,0-5.659-13.467-11.633-28.644c-5.974-15.177-12.274-31.86-13.669-39.536c-1.294-7.054-2.588-12.736-4.748-16.28
c-2.16-3.533-4.759-5.265-10.508-4.927c-2.599,0.157-4.039,1.181-5.209,2.88c-1.17,1.699-1.924,4.264-2.228,7.256
c-0.607,5.985,0.45,13.478,1.204,18.699c3.454,23.874,11.937,46.632,16.561,70.687c2.756,14.322,3.893,28.925,6.514,42.888
l0.743,4.185l-3.724-1.958c-1.766-0.923-3.015-2.531-4.275-4.467c-1.271-1.935-2.464-4.286-3.724-6.694
c-2.509-4.815-5.186-10.036-7.628-12.927c-3.78-4.478-8.449-9.473-13.388-12.466c-4.883-2.959-9.676-3.915-14.885-1.305
c-2.306,2.093-3.139,3.983-3.162,6.143c-0.022,2.25,0.889,4.86,2.329,7.628c2.869,5.535,7.752,11.397,9.203,17.483
c3.611,15.154,12.781,26.978,20.926,39.904c6.368,10.105,11.093,21.23,20.926,26.227c12.972,6.592,24.256,17.01,37.116,19.16
c15.616,2.61,33.076,3.397,48.084,1.394c14.873-1.981,27.103-6.851,32.828-14.604c12.297-49.862,4.534-82.32-15.335-109.468V162.801
z"/>
</svg>

After

Width:  |  Height:  |  Size: 1.9 KiB

44
custom-example/res/Images/PairingConnected.svg

@ -0,0 +1,44 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.6, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 360 72" style="enable-background:new 0 0 360 72;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
.st1{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
.st2{fill:none;stroke:#FFFFFF;stroke-width:2;stroke-linecap:round;stroke-linejoin:round;stroke-miterlimit:4.2573;stroke-dasharray:2,6,2,6;}
.st3{fill:#0CA678;}
</style>
<path class="st0" d="M349.779,17.419h-30.656c-5.646,0-10.221,4.605-10.221,10.288v20.571c0,2.827,2.299,5.141,5.107,5.141h5.107
l2.825-5.684c1.258-2.531,4.587-4.599,7.395-4.599h10.226c2.808,0,6.137,2.067,7.395,4.599l2.825,5.684h5.107
c2.808,0,5.107-2.314,5.107-5.141V27.708C360,22.03,355.426,17.419,349.779,17.419L349.779,17.419z M321.681,35.422
c-2.821,0-5.107-2.302-5.107-5.147c0-2.839,2.287-5.141,5.107-5.141c2.82,0,5.107,2.302,5.107,5.141
C326.788,33.12,324.506,35.422,321.681,35.422z M347.229,35.422c-2.821,0-5.107-2.302-5.107-5.147c0-2.839,2.287-5.141,5.107-5.141
c2.82,0,5.107,2.302,5.107,5.141C352.337,33.12,350.049,35.422,347.229,35.422z"/>
<path class="st1" d="M39.568,25.298l5.557-4.015c-1.334-2.006-2-4.237-2-6.913c0-6.691,5.336-12.042,12.003-12.042
c6.891,0,12.227,5.353,12.227,12.042c0,6.913-5.336,12.266-12.227,12.266c-2.223,0-4.447-0.668-6.225-1.784l-4.223,5.799v11.596
l3.778,5.129c1.779-1.338,4.223-2.006,6.67-2.006c6.67,0,12.003,5.575,12.003,12.266s-5.336,12.042-12.003,12.042
c-6.67,0-12.226-5.353-12.226-12.042c0-2.452,0.889-4.683,2-6.691l-5.781-4.015H27.784l-5.112,3.791
c1.334,2.006,2.223,4.237,2.223,6.913c0,6.691-5.557,12.042-12.227,12.042c-6.67,0-12.003-5.353-12.003-12.042
c0-6.691,5.336-12.266,12.003-12.266c2.444,0,4.668,0.668,6.446,2.006l4.002-5.575v-11.82l-4.223-5.353
c-2,1.114-4.223,2.006-6.891,2.006C5.333,26.631,0,21.277,0,14.364C0,7.673,5.336,2.323,12.003,2.323
c6.891,0,12.227,5.353,12.227,12.042c0,2.452-0.666,4.907-2,6.691l6.002,4.237h11.337L39.568,25.298z M49.793,49.16l3.778,5.353
l2.889,2.898c0.221,0.668-1.11,2.006-1.555,1.784l-3.113-3.344l-5.112-3.569c-0.889,1.56-1.555,3.344-1.555,5.353
c0,5.353,4.447,9.812,10.004,9.812c5.336,0,9.78-4.461,9.78-9.812c0-5.575-4.447-10.036-9.78-10.036
C53.129,47.599,51.351,48.267,49.793,49.16L49.793,49.16z M46.904,19.944l4.891-3.569l2.889-2.898c0.666-0.668,2,1.114,1.779,1.56
l-2.889,3.123l-3.334,4.907c1.334,0.892,3.113,1.338,4.891,1.338c5.557,0,10.004-4.461,10.004-10.036
c0-5.353-4.447-9.812-10.004-9.812c-5.336,0-9.78,4.461-9.78,9.812c0,2.006,0.666,4.015,1.555,5.575L46.904,19.944z M17.562,22.843
l-3.778-5.129l-2.889-2.677c-0.221-0.446,1.11-1.784,1.779-1.56l2.889,2.898l4.891,3.569c0.889-1.56,1.555-3.569,1.555-5.575
c0-5.353-4.447-9.812-10.004-9.812c-5.336,0-9.78,4.461-9.78,9.812c0,5.575,4.447,10.036,9.78,10.036
c2.223,0,4.002-0.668,5.557-1.56L17.562,22.843z M20.896,52.058l-5.336,3.79l-2.889,3.345c-0.666,0.222-2-1.114-1.779-1.784
l2.889-2.898l4.002-5.353c-1.555-0.892-3.113-1.56-5.112-1.56c-5.336,0-9.78,4.461-9.78,10.036c0,5.575,4.447,9.812,9.78,9.812
c5.557,0,10.004-4.237,10.004-9.812C22.675,55.627,22.009,53.618,20.896,52.058L20.896,52.058z"/>
<line class="st2" x1="81.29" y1="34.839" x2="297.29" y2="34.839"/>
<rect x="184.065" y="26.323" class="st0" width="19.355" height="18.387"/>
<path class="st3" d="M206.948,24.149l-13.7-7.298c-0.426-0.238-0.948-0.238-1.375,0l-13.271,7.298
c-0.474,0.238-0.758,0.711-0.758,1.232v10.334c0,8.105,4.833,15.5,12.277,18.769l1.849,0.806c0.188,0.094,0.379,0.094,0.568,0.094
c0.188,0,0.379-0.047,0.568-0.094l2.085-0.9c7.587-3.223,12.516-10.617,12.516-18.864V25.383
C207.706,24.861,207.422,24.387,206.948,24.149L206.948,24.149z M199.931,34.198l-8.389,6.826c-0.285,0.238-0.568,0.332-0.9,0.332
c-0.379,0-0.806-0.189-1.09-0.521l-3.601-4.219c-0.521-0.617-0.427-1.517,0.141-1.991c0.618-0.521,1.518-0.426,1.992,0.142
l2.701,3.175l7.3-5.971c0.617-0.474,1.517-0.426,1.99,0.189C200.642,32.825,200.548,33.725,199.931,34.198L199.931,34.198z"/>
</svg>

After

Width:  |  Height:  |  Size: 4.0 KiB

11
custom-example/res/Images/PairingError.svg

@ -0,0 +1,11 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.6, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 288 288" style="enable-background:new 0 0 288 288;" xml:space="preserve">
<style type="text/css">
.st0{fill:#C92A30;}
</style>
<path class="st0" d="M279.208,90.739c-35.477-36.963-83.184-57.313-134.318-57.313c-51.541,0-101.247,21.676-136.384,59.487
l-8.503,9.142l142.983,152.52l145.017-154.67L279.208,90.739z M158.864,196.782h-29.737v-29.737h29.737V196.782z M158.864,150.006
h-29.737v-83.38h29.737V150.006z"/>
</svg>

After

Width:  |  Height:  |  Size: 694 B

31
custom-example/res/Images/PairingIcon.svg

@ -0,0 +1,31 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.6, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 288 288" style="enable-background:new 0 0 288 288;" xml:space="preserve">
<style type="text/css">
.st0{fill:#FFFFFF;}
.st1{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
</style>
<path class="st0" d="M95.992,203.994h-71.99c-13.259,0-24.001,10.743-24.001,24.001v47.988c0,6.594,5.399,11.993,11.993,11.993
h11.993l6.636-13.258c2.953-5.906,10.771-10.729,17.365-10.729h24.016c6.594,0,14.411,4.823,17.364,10.729l6.636,13.258H108
c6.594,0,11.993-5.399,11.993-11.993v-47.988C119.993,214.751,109.25,203.994,95.992,203.994L95.992,203.994z M30.006,245.993
c-6.623,0-11.993-5.37-11.993-12.007c0-6.623,5.37-11.993,11.993-11.993c6.622,0,11.994,5.37,11.994,11.993
C41.999,240.623,36.642,245.993,30.006,245.993z M90.002,245.993c-6.623,0-11.993-5.37-11.993-12.007
c0-6.623,5.37-11.993,11.993-11.993c6.622,0,11.993,5.37,11.993,11.993C101.996,240.623,96.624,245.993,90.002,245.993z"/>
<path class="st1" d="M287.974,0.034v24.001l-0.002-0.014h-29.991v24.001h5.99c13.274,0,24.001,10.743,24.001,24.001L288,96.025
c0,13.259-10.742,24.001-24.001,24.001h-19.586c12.443,25.38,19.586,53.81,19.586,83.983c0,19.868-16.128,35.995-35.995,35.995
h-35.995v-23.987h35.995c6.622,0,12.008-5.385,12.008-12.008c-0.029-30.426-8.296-58.884-22.526-83.49
c-5.722,1.013-11.853,3.712-15.114,6.96c-4.093,4.106-7.452,7.467-7.452,7.467c-5.849,5.864-12.767,10.658-20.36,14.214
c3.403,5.499,5.456,11.924,5.456,18.87c0,19.881-16.128,35.995-35.995,35.995c-19.896,0-36.009-16.114-36.009-35.995
c0-6.946,2.053-13.372,5.456-18.87c-7.594-3.571-14.511-8.352-20.374-14.229c0,0-3.361-3.346-7.452-7.452
c-3.234-3.234-9.323-5.933-15.003-6.96c-10.376,18.037-17.59,38.09-20.697,59.503H25.644c2.672-21.316,9.013-41.451,18.081-59.996
H24.014c-13.274,0-24.001-10.742-24.001-24.001V72.024C0.012,58.779,10.74,48.037,24,48.037h6.004V24.036H0.012V0.034L83.996,0.02
v24.001H54.005v24.001l0.182,0.014h11.994c6.594,0,15.34-3.346,19.446-7.452l7.452-7.452c13.037-13.034,31.032-21.091,50.915-21.091
s37.88,8.057,50.9,21.077c0,0,3.346,3.36,7.452,7.465c4.091,4.106,12.866,7.452,19.446,7.452h12.19V24.036h-29.991V0.034H287.974z
M132.001,168.015c0,6.623,5.357,11.993,11.993,11.993c6.622,0,12.008-5.37,11.993-11.993c0-6.636-5.372-12.008-11.993-12.008
S132.001,161.379,132.001,168.015z M195.332,70.369l-26.937-19.418c-2.131-1.46-4.936,0.338-4.49,2.806l2.245,13.022h-28.953
c-1.569,0-2.92,1.346-2.92,2.919v5.836c0,1.569,1.346,2.92,2.92,2.92h28.844l-2.245,13.021c-0.448,2.583,2.468,4.376,4.49,2.806
l27.05-19.418c1.68-1.013,1.68-3.372-0.004-4.493V70.369z M149.315,90.91h-28.953l2.245-13.022c0.446-2.582-2.468-4.376-4.49-2.806
L91.18,94.391c-1.571,1.122-1.571,3.59,0,4.713l27.05,19.418c2.131,1.46,4.937-0.338,4.49-2.806l-2.245-13.022h28.844
c1.569,0,2.92-1.346,2.92-2.919v-5.836c-0.119-1.683-1.351-3.03-2.925-3.03V90.91z"/>
</svg>

After

Width:  |  Height:  |  Size: 3.0 KiB

0
src/PairingManager/Images/PairingIconLight.svg → custom-example/res/Images/PairingIconLight.svg

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

40
custom-example/res/MainToolbar/CustomMainToolBarIndicators.qml

@ -23,6 +23,29 @@ import QGroundControl.Palette 1.0
Item { Item {
anchors.fill: parent anchors.fill: parent
readonly property real _indicatorMargins: ScreenTools.defaultFontPixelHeight * 0.75 readonly property real _indicatorMargins: ScreenTools.defaultFontPixelHeight * 0.75
Component.onCompleted: {
if(QGroundControl.pairingManager) {
if(!activeVehicle) {
pairingTimer.start()
}
}
}
//-------------------------------------------------------------------------
//-- Launch pairing manager if nothing connected
Timer {
id: pairingTimer
interval: 5000
running: false;
repeat: false;
onTriggered: {
if(!activeVehicle) {
if(QGroundControl.pairingManager.firstBoot && pairingLoader.item) {
QGroundControl.pairingManager.firstBoot = false
pairingLoader.item.runPairing()
}
}
}
}
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
//-- Waiting for a vehicle //-- Waiting for a vehicle
Row { Row {
@ -34,7 +57,6 @@ Item {
anchors.left: parent.left anchors.left: parent.left
QGCColoredImage { QGCColoredImage {
id: menuEdge id: menuEdge
visible: !QGroundControl.supportsPairing || !QGroundControl.settingsManager.appSettings.usePairing.rawValue
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
height: ScreenTools.defaultFontPixelHeight height: ScreenTools.defaultFontPixelHeight
width: height width: height
@ -44,18 +66,28 @@ Item {
color: qgcPal.buttonText color: qgcPal.buttonText
} }
QGCLabel { QGCLabel {
visible: menuEdge.visible
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
text: qsTr("Waiting for a vehicle") text: qsTr("Waiting for a vehicle")
font.pointSize: ScreenTools.mediumFontPointSize font.pointSize: ScreenTools.mediumFontPointSize
font.family: ScreenTools.demiboldFontFamily font.family: ScreenTools.demiboldFontFamily
} }
}
//-------------------------------------------------------------------------
//-- Pairing Indicator (not connected)
Row {
id: pairingRow
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.rightMargin: ScreenTools.defaultFontPixelWidth * 2
spacing: ScreenTools.defaultFontPixelWidth * 2
visible: !indicatorRow.visible
Loader { Loader {
visible: !menuEdge.visible id: pairingLoader
anchors.top: parent.top anchors.top: parent.top
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.margins: _indicatorMargins anchors.margins: _indicatorMargins
source: "/toolbar/PairingIndicator.qml" source: "/custom/PairingIndicator.qml"
} }
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------

443
src/ui/toolbar/PairingIndicator.qml → custom-example/res/PairingIndicator.qml

@ -10,6 +10,7 @@
import QtQuick 2.11 import QtQuick 2.11
import QtQuick.Controls 2.4 import QtQuick.Controls 2.4
import QtQuick.Layouts 1.11 import QtQuick.Layouts 1.11
import QtQuick.Dialogs 1.3
import QGroundControl 1.0 import QGroundControl 1.0
import QGroundControl.Controls 1.0 import QGroundControl.Controls 1.0
@ -24,20 +25,48 @@ Item {
width: pairingRow.width * 1.1 width: pairingRow.width * 1.1
anchors.top: parent.top anchors.top: parent.top
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
property bool _light: qgcPal.globalTheme === QGCPalette.Light && !activeVehicle
property real _contentWidth: ScreenTools.defaultFontPixelWidth * 30 property bool _light: qgcPal.globalTheme === QGCPalette.Light && !activeVehicle
property real _contentSpacing: ScreenTools.defaultFontPixelHeight * 0.5 property real _contentWidth: ScreenTools.defaultFontPixelWidth * 34
property real _contentSpacing: ScreenTools.defaultFontPixelHeight * 0.5
property real _rectWidth: _contentWidth
property real _rectHeight: _contentWidth * 0.75
property string kPairingManager: qsTr("Pairing Manager")
function runPairing() {
QGroundControl.pairingManager.firstBoot = false
if(QGroundControl.pairingManager.pairedDeviceNameList.length > 0) {
connectionPopup.open()
} else {
mhPopup.open()
}
}
Connections {
target: QGroundControl.pairingManager
//-- Connect automatically once paired
onPairingStatusChanged: {
if(QGroundControl.pairingManager.pairingStatus === PairingManager.PairingSuccess) {
if(QGroundControl.pairingManager.pairedVehicle !== "") {
QGroundControl.pairingManager.connectToPairedDevice(QGroundControl.pairingManager.pairedVehicle)
}
}
}
}
Row { Row {
id: pairingRow id: pairingRow
spacing: ScreenTools.defaultFontPixelWidth spacing: ScreenTools.defaultFontPixelWidth
anchors.top: parent.top anchors.top: parent.top
anchors.bottom: parent.bottom anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
Image { QGCColoredImage {
id: pairingIcon id: pairingIcon
height: parent.height height: parent.height
width: height width: height
source: _light ? "/qmlimages/PairingIconLight.svg" : "/qmlimages/PairingIcon.svg" color: qgcPal.text
source: "/custom/img/PairingIcon.svg"
sourceSize.width: width sourceSize.width: width
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
smooth: true smooth: true
@ -49,7 +78,6 @@ Item {
text: qsTr("Pair Vehicle") text: qsTr("Pair Vehicle")
width: !activeVehicle ? (ScreenTools.defaultFontPixelWidth * 12) : 0 width: !activeVehicle ? (ScreenTools.defaultFontPixelWidth * 12) : 0
visible: !activeVehicle visible: !activeVehicle
font.pointSize: ScreenTools.mediumFontPointSize
font.family: ScreenTools.demiboldFontFamily font.family: ScreenTools.demiboldFontFamily
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
@ -57,90 +85,7 @@ Item {
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
onClicked: { onClicked: {
if(QGroundControl.pairingManager.pairedDeviceNameList.length > 1) { runPairing()
connectionPopup.open()
} else {
if(QGroundControl.pairingManager.pairingLinkTypeStrings.length > 1)
pairingPopup.open()
else {
mhPopup.open()
}
}
}
}
//-------------------------------------------------------------------------
//-- Pairing
Popup {
id: pairingPopup
width: pairingBody.width
height: pairingBody.height
modal: true
focus: true
parent: Overlay.overlay
x: Math.round((mainWindow.width - width) * 0.5)
y: Math.round((mainWindow.height - height) * 0.5)
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
background: Rectangle {
anchors.fill: parent
color: qgcPal.globalTheme === QGCPalette.Light ? Qt.rgba(1,1,1,0.95) : Qt.rgba(0,0,0,0.75)
radius: ScreenTools.defaultFontPixelWidth * 0.25
}
Item {
id: pairingBody
width: comboListCol.width + (ScreenTools.defaultFontPixelWidth * 8)
height: comboListCol.height + (ScreenTools.defaultFontPixelHeight * 2)
anchors.centerIn: parent
Column {
id: comboListCol
spacing: _contentSpacing
anchors.centerIn: parent
Item { width: 1; height: 1; }
QGCLabel {
text: qsTr("Pair New Vehicle")
font.pointSize: ScreenTools.mediumFontPointSize
font.family: ScreenTools.demiboldFontFamily
anchors.horizontalCenter: parent.horizontalCenter
}
Item { width: 1; height: 1; }
Rectangle {
width: ScreenTools.defaultFontPixelWidth * 40
height: ScreenTools.defaultFontPixelHeight * 8
color: Qt.rgba(0,0,0,0)
border.color: qgcPal.text
border.width: 1
anchors.horizontalCenter: parent.horizontalCenter
QGCLabel {
text: "Graphic"
anchors.centerIn: parent
}
}
Item { width: 1; height: 1; }
QGCLabel {
text: qsTr("Please choose a pairing method in order to connect to a nearby device")
width: _contentWidth
wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignHCenter
anchors.horizontalCenter: parent.horizontalCenter
}
Item { width: 1; height: 1; }
Repeater {
model: QGroundControl.pairingManager ? QGroundControl.pairingManager.pairingLinkTypeStrings : []
delegate: QGCButton {
text: modelData
width: _contentWidth
anchors.horizontalCenter: parent.horizontalCenter
onClicked: {
pairingPopup.close()
if (index === QGroundControl.pairingManager.nfcIndex) {
nfcPopup.open()
} else if (index === QGroundControl.pairingManager.microhardIndex) {
mhPopup.open()
}
}
}
}
Item { width: 1; height: 1; }
}
} }
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
@ -171,40 +116,44 @@ Item {
anchors.centerIn: parent anchors.centerIn: parent
Item { width: 1; height: 1; } Item { width: 1; height: 1; }
QGCLabel { QGCLabel {
text: qsTr("Pair New Vehicle") text: kPairingManager
font.pointSize: ScreenTools.mediumFontPointSize
font.family: ScreenTools.demiboldFontFamily font.family: ScreenTools.demiboldFontFamily
font.pointSize: ScreenTools.mediumFontPointSize
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
} }
Rectangle {
width: _contentWidth
height: 1
color: qgcPal.globalTheme !== QGCPalette.Light ? Qt.rgba(1,1,1,0.25) : Qt.rgba(0,0,0,0.25)
}
Item { width: 1; height: 1; } Item { width: 1; height: 1; }
QGCLabel { QGCLabel {
text: qsTr("To connect to your vehicle, please click 3 times on the button in order to put the vehicle in a discovery mode") text: qsTr("To connect to your vehicle, please click on the pairing button in order to put the vehicle in discovery mode")
width: _contentWidth width: _contentWidth
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignHCenter horizontalAlignment: Text.AlignHCenter
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
} }
Item { width: 1; height: 1; } Item { width: 1; height: ScreenTools.defaultFontPixelHeight * 2; }
Rectangle { QGCColoredImage {
width: ScreenTools.defaultFontPixelWidth * 40 height: ScreenTools.defaultFontPixelHeight * 6
height: ScreenTools.defaultFontPixelHeight * 8 width: height
color: Qt.rgba(0,0,0,0) source: "/custom/img/PairingButton.svg"
border.color: qgcPal.text sourceSize.height: height
border.width: 1 fillMode: Image.PreserveAspectFit
mipmap: true
smooth: true
color: qgcPal.text
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
QGCLabel {
text: "Graphic"
anchors.centerIn: parent
}
} }
Item { width: 1; height: 1; } Item { width: 1; height: ScreenTools.defaultFontPixelHeight * 2; }
QGCButton { QGCButton {
text: qsTr("Pair Via Microhard") text: qsTr("Pair a Vehicle")
width: _contentWidth width: _contentWidth
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
onClicked: { onClicked: {
mhPopup.close() mhPopup.close()
connectionPopup.open() progressPopup.open()
QGroundControl.pairingManager.startMicrohardPairing(); QGroundControl.pairingManager.startMicrohardPairing();
} }
} }
@ -240,21 +189,26 @@ Item {
anchors.centerIn: parent anchors.centerIn: parent
Item { width: 1; height: 1; } Item { width: 1; height: 1; }
QGCLabel { QGCLabel {
text: qsTr("Pair New Vehicle") text: kPairingManager
font.pointSize: ScreenTools.mediumFontPointSize
font.family: ScreenTools.demiboldFontFamily font.family: ScreenTools.demiboldFontFamily
font.pointSize: ScreenTools.mediumFontPointSize
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
} }
Rectangle {
width: _contentWidth
height: 1
color: qgcPal.globalTheme !== QGCPalette.Light ? Qt.rgba(1,1,1,0.25) : Qt.rgba(0,0,0,0.25)
}
Item { width: 1; height: 1; } Item { width: 1; height: 1; }
Rectangle { Rectangle {
width: ScreenTools.defaultFontPixelWidth * 40 width: _rectWidth
height: ScreenTools.defaultFontPixelHeight * 12 height: _rectHeight
color: Qt.rgba(0,0,0,0) color: Qt.rgba(0,0,0,0)
border.color: qgcPal.text border.color: qgcPal.text
border.width: 1 border.width: 1
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
QGCLabel { QGCLabel {
text: "Graphic" text: "Vehicle and Tablet Graphic"
anchors.centerIn: parent anchors.centerIn: parent
} }
} }
@ -273,7 +227,7 @@ Item {
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
onClicked: { onClicked: {
nfcPopup.close() nfcPopup.close()
connectionPopup.open() progressPopup.open()
QGroundControl.pairingManager.startNFCScan(); QGroundControl.pairingManager.startNFCScan();
} }
} }
@ -282,11 +236,11 @@ Item {
} }
} }
//------------------------------------------------------------------------- //-------------------------------------------------------------------------
//-- Connection Manager //-- Pairing/Connection Progress
Popup { Popup {
id: connectionPopup id: progressPopup
width: connectionBody.width width: progressBody.width
height: connectionBody.height height: progressBody.height
modal: true modal: true
focus: true focus: true
parent: Overlay.overlay parent: Overlay.overlay
@ -299,25 +253,37 @@ Item {
radius: ScreenTools.defaultFontPixelWidth * 0.25 radius: ScreenTools.defaultFontPixelWidth * 0.25
} }
Item { Item {
id: connectionBody id: progressBody
width: connectionCol.width + (ScreenTools.defaultFontPixelWidth * 8) width: progressCol.width + (ScreenTools.defaultFontPixelWidth * 8)
height: connectionCol.height + (ScreenTools.defaultFontPixelHeight * 2) height: progressCol.height + (ScreenTools.defaultFontPixelHeight * 2)
anchors.centerIn: parent anchors.centerIn: parent
Column { Column {
id: connectionCol id: progressCol
spacing: _contentSpacing * 2 spacing: _contentSpacing
anchors.centerIn: parent anchors.centerIn: parent
Item { width: 1; height: 1; } Item { width: 1; height: 1; }
QGCLabel { QGCLabel {
text: QGroundControl.pairingManager ? QGroundControl.pairingManager.pairingStatusStr : "" text: kPairingManager
font.pointSize: ScreenTools.mediumFontPointSize font.family: ScreenTools.demiboldFontFamily
font.family: ScreenTools.demiboldFontFamily font.pointSize: ScreenTools.mediumFontPointSize
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
} }
QGCLabel {
text: QGroundControl.pairingManager ? QGroundControl.pairingManager.pairingStatusStr : ""
visible: !connectedIndicator.visible
anchors.horizontalCenter: parent.horizontalCenter
}
Rectangle {
width: _contentWidth
height: 1
color: qgcPal.globalTheme !== QGCPalette.Light ? Qt.rgba(1,1,1,0.25) : Qt.rgba(0,0,0,0.25)
}
Item { width: 1; height: 1; } Item { width: 1; height: 1; }
//-- Pairing/Connecting
Item { width: 1; height: ScreenTools.defaultFontPixelHeight * 3; visible: busyIndicator.visible; }
QGCColoredImage { QGCColoredImage {
id: busyIndicator id: busyIndicator
height: ScreenTools.defaultFontPixelHeight * 2 height: ScreenTools.defaultFontPixelHeight * 4
width: height width: height
source: "/qmlimages/MapSync.svg" source: "/qmlimages/MapSync.svg"
sourceSize.height: height sourceSize.height: height
@ -325,7 +291,7 @@ Item {
mipmap: true mipmap: true
smooth: true smooth: true
color: qgcPal.text color: qgcPal.text
visible: cancelButton.visible visible: QGroundControl.pairingManager.pairingStatus === PairingManager.PairingActive || QGroundControl.pairingManager.pairingStatus === PairingManager.PairingConnecting
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
RotationAnimation on rotation { RotationAnimation on rotation {
loops: Animation.Infinite loops: Animation.Infinite
@ -335,10 +301,135 @@ Item {
running: busyIndicator.visible running: busyIndicator.visible
} }
} }
Item { width: 1; height: ScreenTools.defaultFontPixelHeight * 3; visible: busyIndicator.visible; }
//-- Error State
Image {
height: ScreenTools.defaultFontPixelHeight * 4
width: height
source: "/custom/img/PairingError.svg"
sourceSize.height: height
fillMode: Image.PreserveAspectFit
mipmap: true
smooth: true
visible: QGroundControl.pairingManager.errorState
anchors.horizontalCenter: parent.horizontalCenter
}
//-- Connection Successful
Image {
id: connectedIndicator
height: width * 0.2
width: _contentWidth
source: "/custom/img/PairingConnected.svg"
sourceSize.height: height
fillMode: Image.PreserveAspectFit
mipmap: true
smooth: true
visible: QGroundControl.pairingManager.pairingStatus === PairingManager.PairingConnected
anchors.horizontalCenter: parent.horizontalCenter
}
Item { width: 1; height: _contentSpacing; visible: connectedIndicator.visible; }
QGCLabel {
text: QGroundControl.pairingManager.pairedVehicle
visible: connectedIndicator.visible
anchors.horizontalCenter: parent.horizontalCenter
}
QGCLabel {
text: qsTr("Connection Successful")
visible: connectedIndicator.visible
anchors.horizontalCenter: parent.horizontalCenter
}
Item { width: 1; height: _contentSpacing; }
//-- Buttons
QGCButton {
width: _contentWidth
visible: QGroundControl.pairingManager ? (QGroundControl.pairingManager.pairingStatus === PairingManager.PairingConnected) : false
text: qsTr("Done")
anchors.horizontalCenter: parent.horizontalCenter
onClicked: {
progressPopup.close()
}
}
QGCButton {
text: qsTr("Pair Another")
width: _contentWidth
visible: QGroundControl.pairingManager ? (QGroundControl.pairingManager.pairingStatus === PairingManager.PairingConnected) : false
anchors.horizontalCenter: parent.horizontalCenter
onClicked: {
progressPopup.close()
mhPopup.open()
}
}
QGCButton {
text: qsTr("Try Again")
width: _contentWidth
visible: QGroundControl.pairingManager ? QGroundControl.pairingManager.errorState : false
anchors.horizontalCenter: parent.horizontalCenter
onClicked: {
progressPopup.close()
runPairing()
}
}
QGCButton {
id: cancelButton
width: _contentWidth
visible: QGroundControl.pairingManager ? (QGroundControl.pairingManager.pairingStatus === PairingManager.PairingActive || QGroundControl.pairingManager.pairingStatus === PairingManager.PairingConnecting || QGroundControl.pairingManager.errorState) : false
text: qsTr("Cancel")
anchors.horizontalCenter: parent.horizontalCenter
onClicked: {
if(QGroundControl.pairingManager.pairingStatus === PairingManager.PairingActive)
QGroundControl.pairingManager.stopPairing()
else {
//-- TODO: Cancel connection to paired device
}
progressPopup.close()
}
}
Item { width: 1; height: 1; }
}
}
}
//-------------------------------------------------------------------------
//-- Connection Manager
Popup {
id: connectionPopup
width: connectionBody.width
height: connectionBody.height
modal: true
focus: true
parent: Overlay.overlay
x: Math.round((mainWindow.width - width) * 0.5)
y: Math.round((mainWindow.height - height) * 0.5)
closePolicy: cancelButton.visible ? Popup.NoAutoClose : (Popup.CloseOnEscape | Popup.CloseOnPressOutside)
background: Rectangle {
anchors.fill: parent
color: qgcPal.globalTheme === QGCPalette.Light ? Qt.rgba(1,1,1,0.95) : Qt.rgba(0,0,0,0.75)
radius: ScreenTools.defaultFontPixelWidth * 0.25
}
Item {
id: connectionBody
width: connectionCol.width + (ScreenTools.defaultFontPixelWidth * 8)
height: connectionCol.height + (ScreenTools.defaultFontPixelHeight * 2)
anchors.centerIn: parent
Column {
id: connectionCol
spacing: _contentSpacing
anchors.centerIn: parent
Item { width: 1; height: 1; }
QGCLabel {
text: kPairingManager
font.family: ScreenTools.demiboldFontFamily
font.pointSize: ScreenTools.mediumFontPointSize
anchors.horizontalCenter: parent.horizontalCenter
}
Rectangle {
width: _contentWidth
height: 1
color: qgcPal.globalTheme !== QGCPalette.Light ? Qt.rgba(1,1,1,0.25) : Qt.rgba(0,0,0,0.25)
}
Item { width: 1; height: 1; }
QGCLabel { QGCLabel {
text: qsTr("List Of Available Devices") text: qsTr("List Of Available Devices")
visible: QGroundControl.pairingManager ? (QGroundControl.pairingManager.pairedDeviceNameList.length > 0 && !cancelButton.visible) : false visible: QGroundControl.pairingManager ? (QGroundControl.pairingManager.pairedDeviceNameList.length > 0 && !cancelButton.visible) : false
font.pointSize: ScreenTools.mediumFontPointSize
font.family: ScreenTools.demiboldFontFamily font.family: ScreenTools.demiboldFontFamily
} }
Item { width: 1; height: 1; } Item { width: 1; height: 1; }
@ -348,10 +439,11 @@ Item {
columnSpacing: ScreenTools.defaultFontPixelWidth columnSpacing: ScreenTools.defaultFontPixelWidth
rowSpacing: ScreenTools.defaultFontPixelHeight * 0.25 rowSpacing: ScreenTools.defaultFontPixelHeight * 0.25
anchors.horizontalCenter: parent.horizontalCenter anchors.horizontalCenter: parent.horizontalCenter
property var _pairModel: QGroundControl.pairingManager ? QGroundControl.pairingManager.pairedDeviceNameList : []
Repeater { Repeater {
model: QGroundControl.pairingManager ? QGroundControl.pairingManager.pairedDeviceNameList : [] model: parent._pairModel
QGCLabel { delegate: QGCLabel {
text: modelData text: modelData
Layout.row: index Layout.row: index
Layout.column: 0 Layout.column: 0
Layout.minimumWidth:ScreenTools.defaultFontPixelWidth * 14 Layout.minimumWidth:ScreenTools.defaultFontPixelWidth * 14
@ -359,85 +451,64 @@ Item {
} }
} }
Repeater { Repeater {
model: QGroundControl.pairingManager ? QGroundControl.pairingManager.pairedDeviceNameList : [] model: parent._pairModel
QGCButton { delegate: QGCButton {
text: qsTr("Connect") text: qsTr("Connect")
Layout.row: index Layout.row: index
Layout.column: 1 Layout.column: 1
onClicked: { onClicked: {
QGroundControl.pairingManager.connectToPairedDevice(modelData) QGroundControl.pairingManager.connectToPairedDevice(modelData)
connectionPopup.close()
progressPopup.open()
} }
} }
} }
Repeater { Repeater {
model: QGroundControl.pairingManager ? QGroundControl.pairingManager.pairedDeviceNameList : [] model: parent._pairModel
QGCColoredImage { delegate: QGCColoredImage {
height: ScreenTools.defaultFontPixelHeight * 1.5 Layout.preferredWidth: ScreenTools.defaultFontPixelHeight * 1.5
width: height Layout.preferredHeight: ScreenTools.defaultFontPixelHeight * 1.5
sourceSize.height: height sourceSize.height: height
source: "/res/TrashDelete.svg" source: "/res/TrashDelete.svg"
color: qgcPal.colorRed color: qgcPal.colorRed
Layout.row: index Layout.row: index
Layout.column: 2 Layout.column: 2
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
onClicked: { onClicked: {
//-- TODO: removePrompt.open()
} }
} }
} MessageDialog {
} id: removePrompt
} title: qsTr("Remove Paired Vehicle")
Item { width: 1; height: 1; } text: qsTr("Confirm removing %1?").arg(modelData)
RowLayout { standardButtons: StandardButton.Yes | StandardButton.No
id: connectedButtons onNo: removePrompt.close()
visible: QGroundControl.pairingManager ? (QGroundControl.pairingManager.pairingStatus === PairingManager.PairingConnected || QGroundControl.pairingManager.pairingStatus === PairingManager.PairingIdle) : false onYes: {
spacing: ScreenTools.defaultFontPixelWidth * 4 QGroundControl.pairingManager.removePairedDevice(modelData)
anchors.horizontalCenter: parent.horizontalCenter removePrompt.close()
QGCButton { }
text: qsTr("Pair Another")
Layout.minimumWidth: _contentWidth * 0.333
Layout.fillWidth: true
onClicked: {
connectionPopup.close()
if(QGroundControl.pairingManager.pairingLinkTypeStrings.length > 1)
pairingPopup.open()
else {
mhPopup.open()
} }
} }
} }
QGCButton {
text: QGroundControl.pairingManager ? (QGroundControl.pairingManager.pairingStatus === PairingManager.PairingConnected ? qsTr("Go And Fly") : qsTr("Close")) : ""
Layout.minimumWidth: _contentWidth * 0.333
Layout.fillWidth: true
onClicked: {
connectionPopup.close()
}
}
} }
Item { width: 1; height: _contentSpacing; }
QGCButton { QGCButton {
id: cancelButton width: _contentWidth
visible: QGroundControl.pairingManager ? (QGroundControl.pairingManager.pairingStatus === PairingManager.PairingActive || QGroundControl.pairingManager.pairingStatus === PairingManager.PairingConnecting) : false text: qsTr("Close")
text: qsTr("Cancel") anchors.horizontalCenter: parent.horizontalCenter
width: _contentWidth
anchors.horizontalCenter: parent.horizontalCenter
onClicked: { onClicked: {
if(QGroundControl.pairingManager.pairingStatus === PairingManager.PairingActive)
QGroundControl.pairingManager.stopPairing()
else {
//-- TODO: Cancel connection to paired device
}
connectionPopup.close() connectionPopup.close()
} }
} }
QGCButton { QGCButton {
visible: !cancelButton.visible && !connectedButtons.visible text: qsTr("Pair Another")
text: qsTr("Close") width: _contentWidth
width: _contentWidth anchors.horizontalCenter: parent.horizontalCenter
anchors.horizontalCenter: parent.horizontalCenter
onClicked: { onClicked: {
connectionPopup.close() connectionPopup.close()
mhPopup.open()
} }
} }
Item { width: 1; height: 1; } Item { width: 1; height: 1; }

2
custom-example/src/FirmwarePlugin/CustomFirmwarePlugin.cc

@ -56,7 +56,7 @@ CustomFirmwarePlugin::toolBarIndicators(const Vehicle* vehicle)
Q_UNUSED(vehicle); Q_UNUSED(vehicle);
if(_toolBarIndicatorList.size() == 0) { if(_toolBarIndicatorList.size() == 0) {
#if defined(QGC_ENABLE_PAIRING) #if defined(QGC_ENABLE_PAIRING)
_toolBarIndicatorList.append(QVariant::fromValue(QUrl::fromUserInput("qrc:/toolbar/PairingIndicator.qml"))); _toolBarIndicatorList.append(QVariant::fromValue(QUrl::fromUserInput("qrc:/custom/PairingIndicator.qml")));
#endif #endif
_toolBarIndicatorList.append(QVariant::fromValue(QUrl::fromUserInput("qrc:/toolbar/GPSIndicator.qml"))); _toolBarIndicatorList.append(QVariant::fromValue(QUrl::fromUserInput("qrc:/toolbar/GPSIndicator.qml")));
_toolBarIndicatorList.append(QVariant::fromValue(QUrl::fromUserInput("qrc:/toolbar/TelemetryRSSIIndicator.qml"))); _toolBarIndicatorList.append(QVariant::fromValue(QUrl::fromUserInput("qrc:/toolbar/TelemetryRSSIIndicator.qml")));

8
qgcimages.qrc

@ -66,11 +66,11 @@
<file alias="CameraTrigger.svg">src/AutoPilotPlugins/PX4/Images/CameraTrigger.svg</file> <file alias="CameraTrigger.svg">src/AutoPilotPlugins/PX4/Images/CameraTrigger.svg</file>
<file alias="check.svg">resources/check.svg</file> <file alias="check.svg">resources/check.svg</file>
<file alias="checkbox-check.svg">src/QmlControls/checkbox-check.svg</file> <file alias="checkbox-check.svg">src/QmlControls/checkbox-check.svg</file>
<file alias="cOGPointer.svg">src/FlightMap/Images/cOGPointer.svg</file>
<file alias="CogWheel.svg">src/MissionManager/CogWheel.svg</file> <file alias="CogWheel.svg">src/MissionManager/CogWheel.svg</file>
<file alias="compassDottedLine.svg">src/FlightMap/Images/compassDottedLine.svg</file>
<file alias="compassInstrumentArrow.svg">src/FlightMap/Images/compassInstrumentArrow.svg</file> <file alias="compassInstrumentArrow.svg">src/FlightMap/Images/compassInstrumentArrow.svg</file>
<file alias="compassInstrumentDial.svg">src/FlightMap/Images/compassInstrumentDial.svg</file> <file alias="compassInstrumentDial.svg">src/FlightMap/Images/compassInstrumentDial.svg</file>
<file alias="compassDottedLine.svg">src/FlightMap/Images/compassDottedLine.svg</file>
<file alias="cOGPointer.svg">src/FlightMap/Images/cOGPointer.svg</file>
<file alias="Connect.svg">src/ui/toolbar/Images/Connect.svg</file> <file alias="Connect.svg">src/ui/toolbar/Images/Connect.svg</file>
<file alias="crossHair.svg">src/FlightMap/Images/crossHair.svg</file> <file alias="crossHair.svg">src/FlightMap/Images/crossHair.svg</file>
<file alias="DatalinkLoss.svg">src/AutoPilotPlugins/PX4/Images/DatalinkLoss.svg</file> <file alias="DatalinkLoss.svg">src/AutoPilotPlugins/PX4/Images/DatalinkLoss.svg</file>
@ -181,9 +181,5 @@
<file alias="Yield.svg">src/ui/toolbar/Images/Yield.svg</file> <file alias="Yield.svg">src/ui/toolbar/Images/Yield.svg</file>
<file alias="ZoomMinus.svg">src/FlightMap/Images/ZoomMinus.svg</file> <file alias="ZoomMinus.svg">src/FlightMap/Images/ZoomMinus.svg</file>
<file alias="ZoomPlus.svg">src/FlightMap/Images/ZoomPlus.svg</file> <file alias="ZoomPlus.svg">src/FlightMap/Images/ZoomPlus.svg</file>
<file alias="PairingIcon.svg">src/PairingManager/Images/PairingIcon.svg</file>
<file alias="PairingIconLight.svg">src/PairingManager/Images/PairingIconLight.svg</file>
</qresource> </qresource>
</RCC> </RCC>

1
qgroundcontrol.qrc

@ -14,7 +14,6 @@
<file alias="MessageIndicator.qml">src/ui/toolbar/MessageIndicator.qml</file> <file alias="MessageIndicator.qml">src/ui/toolbar/MessageIndicator.qml</file>
<file alias="ModeIndicator.qml">src/ui/toolbar/ModeIndicator.qml</file> <file alias="ModeIndicator.qml">src/ui/toolbar/ModeIndicator.qml</file>
<file alias="MultiVehicleSelector.qml">src/ui/toolbar/MultiVehicleSelector.qml</file> <file alias="MultiVehicleSelector.qml">src/ui/toolbar/MultiVehicleSelector.qml</file>
<file alias="PairingIndicator.qml">src/ui/toolbar/PairingIndicator.qml</file>
<file alias="RCRSSIIndicator.qml">src/ui/toolbar/RCRSSIIndicator.qml</file> <file alias="RCRSSIIndicator.qml">src/ui/toolbar/RCRSSIIndicator.qml</file>
<file alias="TelemetryRSSIIndicator.qml">src/ui/toolbar/TelemetryRSSIIndicator.qml</file> <file alias="TelemetryRSSIIndicator.qml">src/ui/toolbar/TelemetryRSSIIndicator.qml</file>
<file alias="VTOLModeIndicator.qml">src/ui/toolbar/VTOLModeIndicator.qml</file> <file alias="VTOLModeIndicator.qml">src/ui/toolbar/VTOLModeIndicator.qml</file>

23
src/PairingManager/Images/PairingIcon.svg

@ -1,23 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.6, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
viewBox="0 0 288 288" style="enable-background:new 0 0 288 288;" xml:space="preserve">
<style type="text/css">
.st0{fill:#07916D;}
.st1{fill:#FFFFFF;}
</style>
<rect x="45" y="94.5" class="st0" width="128.1" height="136.1"/>
<path class="st1" d="M251.5,247H4.5c-1.3,0-2.3,0.5-3.2,1.3C0.5,249.3,0,250.7,0,252c1.3,20.2,18.4,36,38.7,36h178.7
c20.2,0,37.3-15.8,38.7-36c0-1.3-0.5-2.7-1.3-3.6C253.8,247.5,252.9,247,251.5,247L251.5,247z M137.7,272.3h-19.8
c-2.7,0-4.5-2.3-4.5-4.5c0-2.2,1.8-4.5,4.5-4.5h19.8c2.3,0,4.5,2.3,4.5,4.5C142.2,270,140.4,272.3,137.7,272.3z"/>
<path class="st1" d="M274.5,0h-74.7c-7.6,0-13.5,6.3-13.5,13.5v106.2l101.7,0V13.5C288,6.3,281.7,0,274.5,0L274.5,0z"/>
<path class="st1" d="M186.3,147.2c0,7.6,5.8,13.5,13.5,13.5l74.7,0c7.6,0,13.5-6.3,13.5-13.5v-18.4H186.3V147.2z M230.4,140h13.5
c2.7,0,4.5,1.8,4.5,4.5c0,2.7-1.8,4.5-4.5,4.5h-13.5c-2.7,0-4.5-1.8-4.5-4.5C225.9,141.7,227.7,140,230.4,140z"/>
<path class="st1" d="M18.9,238.1h218.2c2.7,0,4.5-2.3,4.5-4.5v-63.9h-41.8c-12.6,0-22.5-10.3-22.5-22.5V77.4l-149.9,0
c-7.2,0-13.1,5.8-13.1,13.1v143.1C14.4,236.3,16.2,238.1,18.9,238.1L18.9,238.1z M102.6,135.4l27-12.1l-8.6-3.2
c-2.3-0.9-3.6-3.6-2.7-5.8c0.9-2.3,3.6-3.6,5.8-2.7l18.4,6.8c0.9,0.5,2.3,1.3,2.7,2.3c0.5,0.9,0.5,2.3,0,3.6l-6.8,18.4
c-0.9,2.3-3.6,3.6-5.8,2.7c-2.2-0.9-3.6-3.6-2.7-5.8l3.2-8.6l-27,12.1c-2.3,0.9-5,0-5.8-2.3C99,139,100.4,136.4,102.6,135.4
L102.6,135.4z M81,190.8l6.8-18.4c0.9-2.3,3.6-3.6,5.8-2.7c2.3,0.9,3.6,3.6,2.7,5.8l-3.2,8.6l27-12.1c2.3-0.9,5,0,5.8,2.3
c0.9,2.3,0,5-2.2,5.8l-27,12.1l8.6,3.2c2.3,0.9,3.6,3.6,2.7,5.8c-0.9,2.3-3.6,3.6-5.8,2.7l-18.4-6.8c-0.9-0.5-2.3-1.3-2.7-2.3
C81.4,193.9,80.6,193.1,81,190.8L81,190.8z"/>
</svg>

Before

Width:  |  Height:  |  Size: 1.9 KiB

49
src/PairingManager/PairingManager.cc

@ -62,6 +62,8 @@ void
PairingManager::setToolbox(QGCToolbox *toolbox) PairingManager::setToolbox(QGCToolbox *toolbox)
{ {
QGCTool::setToolbox(toolbox); QGCTool::setToolbox(toolbox);
_updatePairedDeviceNameList();
emit pairedListChanged();
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -70,18 +72,21 @@ PairingManager::_pairingCompleted(QString name)
{ {
_writeJson(_jsonDoc, _pairingCacheFile(name)); _writeJson(_jsonDoc, _pairingCacheFile(name));
_remotePairingMap["NM"] = name; _remotePairingMap["NM"] = name;
_lastPaired = name;
_updatePairedDeviceNameList();
emit pairedListChanged(); emit pairedListChanged();
_app->informationMessageBoxOnMainThread("", tr("Paired with %1").arg(name)); emit pairedVehicleChanged();
//_app->informationMessageBoxOnMainThread("", tr("Paired with %1").arg(name));
setPairingStatus(PairingSuccess, tr("Pairing Successfull")); setPairingStatus(PairingSuccess, tr("Pairing Successfull"));
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void void
PairingManager::_connectionCompleted(QString name) PairingManager::_connectionCompleted(QString /*name*/)
{ {
//QString pwd = _remotePairingMap["PWD"].toString(); //QString pwd = _remotePairingMap["PWD"].toString();
//_toolbox->microhardManager()->switchToConnectionEncryptionKey(pwd); //_toolbox->microhardManager()->switchToConnectionEncryptionKey(pwd);
_app->informationMessageBoxOnMainThread("", tr("Connected to %1").arg(name)); //_app->informationMessageBoxOnMainThread("", tr("Connected to %1").arg(name));
setPairingStatus(PairingConnected, tr("Connection Successfull")); setPairingStatus(PairingConnected, tr("Connection Successfull"));
} }
@ -126,7 +131,7 @@ PairingManager::_stopUpload()
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
void void
PairingManager::_uploadFinished(void) PairingManager::_uploadFinished()
{ {
QMutexLocker lock(&_uploadMutex); QMutexLocker lock(&_uploadMutex);
QNetworkReply* reply = qobject_cast<QNetworkReply*>(QObject::sender()); QNetworkReply* reply = qobject_cast<QNetworkReply*>(QObject::sender());
@ -154,7 +159,7 @@ PairingManager::_uploadFinished(void)
} else { } else {
if(++_pairRetryCount > 3) { if(++_pairRetryCount > 3) {
qCDebug(PairingManagerLog) << "Giving up"; qCDebug(PairingManagerLog) << "Giving up";
setPairingStatus(PairingError, tr("Too Many Errors")); setPairingStatus(PairingError, tr("No Response From Vehicle"));
_uploadManager->deleteLater(); _uploadManager->deleteLater();
_uploadManager = nullptr; _uploadManager = nullptr;
} else { } else {
@ -191,18 +196,26 @@ PairingManager::connectToPairedDevice(QString name)
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
QStringList void
PairingManager::pairedDeviceNameList(void) PairingManager::removePairedDevice(QString name)
{ {
QStringList list; QFile file(_pairingCacheFile(name));
file.remove();
_updatePairedDeviceNameList();
emit pairedListChanged();
}
//-----------------------------------------------------------------------------
void
PairingManager::_updatePairedDeviceNameList()
{
_deviceList.clear();
QDirIterator it(_pairingCacheDir().absolutePath(), QDir::Files); QDirIterator it(_pairingCacheDir().absolutePath(), QDir::Files);
while (it.hasNext()) { while (it.hasNext()) {
QFileInfo fileInfo(it.next()); QFileInfo fileInfo(it.next());
list.append(fileInfo.fileName()); _deviceList.append(fileInfo.fileName());
qCDebug(PairingManagerLog) << "Listing: " << fileInfo.fileName(); qCDebug(PairingManagerLog) << "Listing: " << fileInfo.fileName();
} }
return list;
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
@ -215,9 +228,9 @@ PairingManager::_assumeMicrohardPairingJson()
jsonObject.insert("LT", "MH"); jsonObject.insert("LT", "MH");
jsonObject.insert("IP", "192.168.168.10"); jsonObject.insert("IP", "192.168.168.10");
jsonObject.insert("AIP", _toolbox->microhardManager()->remoteIPAddr()); jsonObject.insert("AIP", _toolbox->microhardManager()->remoteIPAddr());
jsonObject.insert("CU", _toolbox->microhardManager()->configUserName()); jsonObject.insert("CU", _toolbox->microhardManager()->configUserName());
jsonObject.insert("CP", _toolbox->microhardManager()->configPassword()); jsonObject.insert("CP", _toolbox->microhardManager()->configPassword());
jsonObject.insert("EK", _toolbox->microhardManager()->encryptionKey()); jsonObject.insert("EK", _toolbox->microhardManager()->encryptionKey());
json.setObject(jsonObject); json.setObject(jsonObject);
return QString(json.toJson(QJsonDocument::Compact)); return QString(json.toJson(QJsonDocument::Compact));
@ -255,8 +268,8 @@ PairingManager::_parsePairingJson(QString jsonEnc)
} }
_remotePairingMap = jsonObj.toVariantMap(); _remotePairingMap = jsonObj.toVariantMap();
QString linkType = _remotePairingMap["LT"].toString(); QString linkType = _remotePairingMap["LT"].toString();
QString pport = _remotePairingMap["PP"].toString(); QString pport = _remotePairingMap["PP"].toString();
if (pport.length()==0) { if (pport.length()==0) {
pport = "29351"; pport = "29351";
} }
@ -438,7 +451,7 @@ PairingManager::_createMicrohardConnectJson(QString cert2)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
QStringList QStringList
PairingManager::pairingLinkTypeStrings(void) PairingManager::pairingLinkTypeStrings()
{ {
//-- Must follow same order as enum LinkType in LinkConfiguration.h //-- Must follow same order as enum LinkType in LinkConfiguration.h
static QStringList list; static QStringList list;
@ -467,7 +480,7 @@ PairingManager::_setPairingStatus(PairingStatus status, QString statusStr)
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
QString QString
PairingManager::pairingStatusStr(void) const PairingManager::pairingStatusStr() const
{ {
return _statusString; return _statusString;
} }

92
src/PairingManager/PairingManager.h

@ -61,18 +61,23 @@ public:
Q_ENUM(PairingStatus) Q_ENUM(PairingStatus)
QStringList pairingLinkTypeStrings(void); QStringList pairingLinkTypeStrings ();
QString pairingStatusStr(void) const; QString pairingStatusStr () const;
QStringList pairedDeviceNameList(void); QStringList pairedDeviceNameList () { return _deviceList; }
PairingStatus pairingStatus() { return _status; } PairingStatus pairingStatus () { return _status; }
int nfcIndex(void) { return _nfcIndex; } QString pairedVehicle () { return _lastPaired; }
int microhardIndex(void) { return _microhardIndex; } int nfcIndex () { return _nfcIndex; }
void setStatusMessage(PairingStatus status, QString statusStr) { emit setPairingStatus(status, statusStr); } int microhardIndex () { return _microhardIndex; }
void jsonReceived(QString json) { emit parsePairingJson(json); } bool firstBoot () { return _firstBoot; }
bool errorState () { return _status == PairingRejected || _status == PairingConnectionRejected || _status == PairingError; }
void setStatusMessage (PairingStatus status, QString statusStr) { emit setPairingStatus(status, statusStr); }
void jsonReceived (QString json) { emit parsePairingJson(json); }
void setFirstBoot (bool set) { _firstBoot = set; emit firstBootChanged(); }
#ifdef __android__ #ifdef __android__
static void setNativeMethods(void); static void setNativeMethods (void);
#endif #endif
Q_INVOKABLE void connectToPairedDevice(QString name); Q_INVOKABLE void connectToPairedDevice (QString name);
Q_INVOKABLE void removePairedDevice (QString name);
#if defined QGC_ENABLE_NFC || defined QGC_ENABLE_QTNFC #if defined QGC_ENABLE_NFC || defined QGC_ENABLE_QTNFC
Q_INVOKABLE void startNFCScan(); Q_INVOKABLE void startNFCScan();
@ -86,29 +91,35 @@ public:
Q_PROPERTY(PairingStatus pairingStatus READ pairingStatus NOTIFY pairingStatusChanged) Q_PROPERTY(PairingStatus pairingStatus READ pairingStatus NOTIFY pairingStatusChanged)
Q_PROPERTY(QStringList pairedDeviceNameList READ pairedDeviceNameList NOTIFY pairedListChanged) Q_PROPERTY(QStringList pairedDeviceNameList READ pairedDeviceNameList NOTIFY pairedListChanged)
Q_PROPERTY(QStringList pairingLinkTypeStrings READ pairingLinkTypeStrings CONSTANT) Q_PROPERTY(QStringList pairingLinkTypeStrings READ pairingLinkTypeStrings CONSTANT)
Q_PROPERTY(QString pairedVehicle READ pairedVehicle NOTIFY pairedVehicleChanged)
Q_PROPERTY(bool errorState READ errorState NOTIFY pairingStatusChanged)
Q_PROPERTY(int nfcIndex READ nfcIndex CONSTANT) Q_PROPERTY(int nfcIndex READ nfcIndex CONSTANT)
Q_PROPERTY(int microhardIndex READ microhardIndex CONSTANT) Q_PROPERTY(int microhardIndex READ microhardIndex CONSTANT)
Q_PROPERTY(bool firstBoot READ firstBoot WRITE setFirstBoot NOTIFY firstBootChanged)
signals: signals:
void startUpload(QString pairURL, QJsonDocument); void startUpload (QString pairURL, QJsonDocument);
void closeConnection(); void closeConnection ();
void pairingConfigurationsChanged(); void pairingConfigurationsChanged ();
void nameListChanged(); void nameListChanged ();
void pairingStatusChanged(); void pairingStatusChanged ();
void parsePairingJson(QString json); void parsePairingJson (QString json);
void setPairingStatus(PairingStatus status, QString pairingStatus); void setPairingStatus (PairingStatus status, QString pairingStatus);
void pairedListChanged(); void pairedListChanged ();
void pairedVehicleChanged ();
void firstBootChanged ();
private slots: private slots:
void _startUpload(QString pairURL, QJsonDocument); void _startUpload (QString pairURL, QJsonDocument);
void _stopUpload(); void _stopUpload ();
void _startUploadRequest(); void _startUploadRequest ();
void _parsePairingJson(QString jsonEnc); void _parsePairingJson (QString jsonEnc);
void _setPairingStatus(PairingStatus status, QString pairingStatus); void _setPairingStatus (PairingStatus status, QString pairingStatus);
private: private:
QString _statusString; QString _statusString;
QString _jsonFileName; QString _jsonFileName;
QString _lastPaired;
QVariantMap _remotePairingMap; QVariantMap _remotePairingMap;
int _nfcIndex = -1; int _nfcIndex = -1;
int _microhardIndex = -1; int _microhardIndex = -1;
@ -120,23 +131,26 @@ private:
QNetworkAccessManager* _uploadManager = nullptr; QNetworkAccessManager* _uploadManager = nullptr;
QString _uploadURL{}; QString _uploadURL{};
QString _uploadData{}; QString _uploadData{};
bool _firstBoot = true;
void _parsePairingJsonFile(); QStringList _deviceList;
QJsonDocument _createZeroTierConnectJson(QString cert2);
QJsonDocument _createMicrohardConnectJson(QString cert2); void _parsePairingJsonFile ();
QJsonDocument _createZeroTierPairingJson(QString cert1); QJsonDocument _createZeroTierConnectJson (QString cert2);
QJsonDocument _createMicrohardPairingJson(QString pwd, QString cert1); QJsonDocument _createMicrohardConnectJson (QString cert2);
QString _assumeMicrohardPairingJson(); QJsonDocument _createZeroTierPairingJson (QString cert1);
void _writeJson(QJsonDocument &jsonDoc, QString fileName); QJsonDocument _createMicrohardPairingJson (QString pwd, QString cert1);
QString _getLocalIPInNetwork(QString remoteIP, int num); QString _assumeMicrohardPairingJson ();
void _uploadFinished(void); void _writeJson (QJsonDocument &jsonDoc, QString fileName);
void _uploadError(QNetworkReply::NetworkError code); QString _getLocalIPInNetwork (QString remoteIP, int num);
void _pairingCompleted(QString name); void _uploadFinished ();
void _connectionCompleted(QString name); void _uploadError (QNetworkReply::NetworkError code);
QDir _pairingCacheDir(); void _pairingCompleted (QString name);
QString _pairingCacheFile(QString uavName); void _connectionCompleted (QString name);
QDir _pairingCacheDir ();
QString _pairingCacheFile (QString uavName);
void _updatePairedDeviceNameList ();
#if defined QGC_ENABLE_NFC || defined QGC_ENABLE_QTNFC #if defined QGC_ENABLE_NFC || defined QGC_ENABLE_QTNFC
PairingNFC pairingNFC; PairingNFC pairingNFC;
#endif #endif
}; };

4
src/ui/preferences/GeneralSettings.qml

@ -484,14 +484,14 @@ Rectangle {
} }
FactCheckBox { FactCheckBox {
text: qsTr("Show additional heading indicators on Compass") text: qsTr("Show additional heading indicators on Compass")
visible: _showAdditionalIndicatorsCompass.visible visible: _showAdditionalIndicatorsCompass ? _showAdditionalIndicatorsCompass.visible : false
fact: _showAdditionalIndicatorsCompass fact: _showAdditionalIndicatorsCompass
property Fact _showAdditionalIndicatorsCompass: QGroundControl.settingsManager.flyViewSettings.showAdditionalIndicatorsCompass property Fact _showAdditionalIndicatorsCompass: QGroundControl.settingsManager.flyViewSettings.showAdditionalIndicatorsCompass
} }
FactCheckBox { FactCheckBox {
text: qsTr("Lock Compass Nose-Up") text: qsTr("Lock Compass Nose-Up")
visible: _lockNoseUpCompass.visible visible: _lockNoseUpCompass ? _lockNoseUpCompass.visible : false
fact: _lockNoseUpCompass fact: _lockNoseUpCompass
property Fact _lockNoseUpCompass: QGroundControl.settingsManager.flyViewSettings.lockNoseUpCompass property Fact _lockNoseUpCompass: QGroundControl.settingsManager.flyViewSettings.lockNoseUpCompass

Loading…
Cancel
Save