Unverified Commit 72c97a09 authored by Don Gagne's avatar Don Gagne Committed by GitHub

Merge pull request #8709 from DonLakeFlyer/CustomExample

Major update to simplify and document the custom build example
parents 4254acfd d68e5586
......@@ -2,27 +2,26 @@
## Custom Build Example
To build this sample custom version, simply rename the directory from `custom-example` to `custom` before running `qmake` (or launching Qt Creator.) The build system will automatically find anything in `custom` and incorporate it into the build. If you had already run a build before renaming the directory, delete the build directory before running `qmake`. To restore the build to a stock QGroundControl one, rename the directory back to `custom-example` (making sure to clean the build directory again.)
To build this sample custom version:
### Custom Builds
* Clean you build directory of any previous build
* Rename the directory from `custom-example` to `custom`
* Change to the `custom` directory
* Run `python updateqrc.py`
* Build QGC
The root project file (`qgroundcontrol.pro`) will look and see if `custom/custom.pri` exists. If it does, it will load it before anything else is setup. This allows you to modify the build in any way necessary for a custom build. This example shows you how to:
![Custom Build Screenshot](README.jpg)
* Fully brand your build
* Define a single flight stack to avoid carrying over unnecessary code
* Implement your own, autopilot and firmware plugin overrides
* Implement your own camera manager and plugin overrides
* Implement your own QtQuick interface module
* Implement your own toolbar, toolbar indicators and UI navigation
* Implement your own Fly View overlay (and how to hide elements from QGC such as the flight widget)
* Implement your own, custom QtQuick camera control
* Implement your own, custom Pre-flight Checklist
* Define your own resources for all of the above
More details on what a custom build is and how to create your own can be found in the [QGC Dev Guide](https://dev.qgroundcontrol.com/en/custom_build/custom_build.html).
Note that within `qgroundcontrol.pro`, most main build steps are surrounded by flags, which you can define to override them. For example, if you want to have your own Android build, done in some completely different way, you simply:
The main features of this example:
```
DEFINES += DISABLE_BUILTIN_ANDROID
```
* Assumes an "Off The Shelf" purchased commercial vehicle. This means most vehicle setup is hidden from the user since they should mostly never need to adjust those things. They would be set up correctly by the vehicle producing company prior to sale.
* The above assumption cause the QGC UI to adjust and not show various things. Providing an even simpler experience to the user.
* The full experience continues to be available in "Advanced Mode".
* Brands the build with various custom images and custom color palette which matches corporate branding of the theoretical commercial company this build is for.
* Customizes portions of the interface such as you can see in the above screenshot which shows a custom instrument widget replacing the standard QGC ui.
* It also overrides various QGC Application settings to hide some settings the users shouldn't modify as well as adjusting defaults for others.
* The source code is fully commented to explain what and why it is doing things.
With this defined within your `custom.pri` file, it is up to you to define how to do the Android build. You can either replace the entire process or prepare it before invoking QGC’s own Android project file on your own. You would do this if you want to have your own branding within the Android manifest. The same applies to iOS (`DISABLE_BUILTIN_IOS`).
> Important Note: This custom build is not automatically built each time regular QGC code changes. This can mean that it may fall out of date with the latest changes in QGC code. This can show up as the `python updateqrc.py` steps failing due to upstream resource changes. Or possibly fail to compile because the plugin mechanism for custom builds has changed. If this happens please notify the QGC devs and they will bring it up to date. Or even better, submit a pull for the fix yourself!
\ No newline at end of file
......@@ -35,36 +35,32 @@ CONFIG += QGC_DISABLE_PX4_PLUGIN_FACTORY
DEFINES += CUSTOMHEADER=\"\\\"CustomPlugin.h\\\"\"
DEFINES += CUSTOMCLASS=CustomPlugin
TARGET = CustomQGC
DEFINES += QGC_APPLICATION_NAME=\"\\\"CustomQGC\\\"\"
TARGET = MyGroundStation
DEFINES += QGC_APPLICATION_NAME='"\\\"Custom QGroundControl\\\""'
DEFINES += QGC_ORG_NAME=\"\\\"qgroundcontrol.org\\\"\"
DEFINES += QGC_ORG_DOMAIN=\"\\\"org.qgroundcontrol\\\"\"
QGC_APP_NAME = "Custom GS"
QGC_BINARY_NAME = "CustomQGC"
QGC_APP_NAME = "Custom QGroundControl"
QGC_BINARY_NAME = "CustomQGroundControl"
QGC_ORG_NAME = "Custom"
QGC_ORG_DOMAIN = "org.qgroundcontrol"
QGC_APP_DESCRIPTION = "Custom QGC Ground Station"
QGC_APP_COPYRIGHT = "Copyright (C) 2019 QGroundControl Development Team. All rights reserved."
QGC_ORG_DOMAIN = "org.custom"
QGC_APP_DESCRIPTION = "Custom QGroundControl"
QGC_APP_COPYRIGHT = "Copyright (C) 2020 QGroundControl Development Team. All rights reserved."
# Our own, custom resources
RESOURCES += \
$$QGCROOT/custom/custom.qrc
$$PWD/custom.qrc
QML_IMPORT_PATH += \
$$QGCROOT/custom/res
$$PWD/res
# Our own, custom sources
SOURCES += \
$$PWD/src/CustomPlugin.cc \
$$PWD/src/CustomQuickInterface.cc \
$$PWD/src/CustomVideoManager.cc
HEADERS += \
$$PWD/src/CustomPlugin.h \
$$PWD/src/CustomQuickInterface.h \
$$PWD/src/CustomVideoManager.h
INCLUDEPATH += \
$$PWD/src \
......@@ -73,20 +69,16 @@ INCLUDEPATH += \
# Custom Firmware/AutoPilot Plugin
INCLUDEPATH += \
$$QGCROOT/custom/src/FirmwarePlugin \
$$QGCROOT/custom/src/AutoPilotPlugin
$$PWD/src/FirmwarePlugin \
$$PWD/src/AutoPilotPlugin
HEADERS+= \
$$QGCROOT/custom/src/AutoPilotPlugin/CustomAutoPilotPlugin.h \
$$QGCROOT/custom/src/FirmwarePlugin/CustomCameraControl.h \
$$QGCROOT/custom/src/FirmwarePlugin/CustomCameraManager.h \
$$QGCROOT/custom/src/FirmwarePlugin/CustomFirmwarePlugin.h \
$$QGCROOT/custom/src/FirmwarePlugin/CustomFirmwarePluginFactory.h \
$$PWD/src/AutoPilotPlugin/CustomAutoPilotPlugin.h \
$$PWD/src/FirmwarePlugin/CustomFirmwarePlugin.h \
$$PWD/src/FirmwarePlugin/CustomFirmwarePluginFactory.h \
SOURCES += \
$$QGCROOT/custom/src/AutoPilotPlugin/CustomAutoPilotPlugin.cc \
$$QGCROOT/custom/src/FirmwarePlugin/CustomCameraControl.cc \
$$QGCROOT/custom/src/FirmwarePlugin/CustomCameraManager.cc \
$$QGCROOT/custom/src/FirmwarePlugin/CustomFirmwarePlugin.cc \
$$QGCROOT/custom/src/FirmwarePlugin/CustomFirmwarePluginFactory.cc \
$$PWD/src/AutoPilotPlugin/CustomAutoPilotPlugin.cc \
$$PWD/src/FirmwarePlugin/CustomFirmwarePlugin.cc \
$$PWD/src/FirmwarePlugin/CustomFirmwarePluginFactory.cc \
<RCC>
<qresource prefix="/custom">
<file alias="CustomArmedIndicator.qml">res/MainToolbar/CustomArmedIndicator.qml</file>
<file alias="CustomBatteryIndicator.qml">res/MainToolbar/CustomBatteryIndicator.qml</file>
<file alias="CustomCameraControl.qml">res/CustomCameraControl.qml</file>
<file alias="CustomFlyView.qml">res/CustomFlyView.qml</file>
<file alias="CustomGPSIndicator.qml">res/MainToolbar/CustomGPSIndicator.qml</file>
<file alias="CustomMainToolBar.qml">res/MainToolbar/CustomMainToolBar.qml</file>
<file alias="CustomMainToolBarIndicators.qml">res/MainToolbar/CustomMainToolBarIndicators.qml</file>
<file alias="CustomModeIndicator.qml">res/MainToolbar/CustomModeIndicator.qml</file>
<file alias="CustomMultiVehicleSelector.qml">res/MainToolbar/CustomMultiVehicleSelector.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="CustomFlyViewOverlay.qml">res/CustomFlyViewOverlay.qml</file>
</qresource>
<qresource prefix="custom/img">
<file alias="altitude.svg">res/Images/altitude.svg</file>
<file alias="attitude_crosshair.svg">res/Images/attitude_crosshair.svg</file>
<file alias="attitude_dial.svg">res/Images/attitude_dial.svg</file>
<file alias="attitude_pointer.svg">res/Images/attitude_pointer.svg</file>
<file alias="camera_photo.svg">res/Images/camera_photo.svg</file>
<file alias="camera_settings.svg">res/Images/camera_settings.svg</file>
<file alias="camera_video.svg">res/Images/camera_video.svg</file>
<file alias="chronometer.svg">res/Images/chronometer.svg</file>
<file alias="compass_needle.svg">res/Images/compass_needle.svg</file>
<file alias="compass_pointer.svg">res/Images/compass_pointer.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_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_position.svg">res/Images/gimbal_position.svg</file>
<file alias="horizontal_speed.svg">res/Images/horizontal_speed.svg</file>
<file alias="microSD.svg">res/Images/microSD.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-palette.svg">res/Images/thermal-palette.svg</file>
<file alias="thermal-pip.svg">res/Images/thermal-pip.svg</file>
<file alias="thermal-standard.svg">res/Images/thermal-standard.svg</file>
<file alias="vertical_speed.svg">res/Images/vertical_speed.svg</file>
<file alias="void.png">res/Images/void.png</file>
<file alias="CustomAppIcon.png">res/Images/CustomAppIcon.png</file>
</qresource>
<qresource prefix="/qmlimages">
<file alias="PaperPlane.svg">res/Images/CustomVehicleIcon.svg</file>
</qresource>
<qresource prefix="Custom/Widgets">
<file alias="Custom/Widgets/CustomArtificialHorizon.qml">res/Custom/Widgets/CustomArtificialHorizon.qml</file>
......@@ -54,8 +31,4 @@
<file alias="Custom/Widgets/CustomVehicleButton.qml">res/Custom/Widgets/CustomVehicleButton.qml</file>
<file alias="Custom/Widgets/qmldir">res/Custom/Widgets/qmldir</file>
</qresource>
<qresource prefix="Custom/Camera">
<file alias="Custom/Camera/qmldir">res/Custom/Camera/qmldir</file>
<file alias="Custom/Camera/ZoomControl.qml">res/Custom/Camera/ZoomControl.qml</file>
</qresource>
</RCC>
<file alias="PaperPlane.svg">src/ui/toolbar/Images/PaperPlane.svg</file>
<RCC>
<qresource prefix="/fonts">
<file alias="opensans">../resources/fonts/OpenSans-Regular.ttf</file>
<file alias="opensans-demibold">../resources/fonts/OpenSans-Semibold.ttf</file>
<file alias="NanumGothic-Regular">../resources/fonts/NanumGothic-Regular.ttf</file>
<file alias="NanumGothic-Bold">../resources/fonts/NanumGothic-Bold.ttf</file>
</qresource>
<qresource prefix="/res">
<file alias="action.svg">../resources/action.svg</file>
<file alias="AntennaRC">../resources/Antenna_RC.svg</file>
<file alias="AntennaT">../resources/Antenna_T.svg</file>
<file alias="ArrowDown.svg">../resources/ArrowDown.svg</file>
<file alias="ArrowRight.svg">../resources/ArrowRight.svg</file>
<file alias="buttonLeft.svg">../resources/buttonLeft.svg</file>
<file alias="buttonRight.svg">../resources/buttonRight.svg</file>
<file alias="cancel.svg">../resources/cancel.svg</file>
<file alias="clockwise-arrow.svg">../resources/clockwise-arrow.svg</file>
<file alias="counter-clockwise-arrow.svg">../resources/counter-clockwise-arrow.svg</file>
<file alias="chevron-down.svg">../resources/chevron-down.svg</file>
<file alias="chevron-up.svg">../resources/chevron-up.svg</file>
<file alias="DropArrow.svg">../resources/DropArrow.svg</file>
<file alias="gear-black.svg">../resources/gear-black.svg</file>
<file alias="gear-white.svg">../resources/gear-white.svg</file>
<file alias="helicoptericon.svg">../resources/helicoptericon.svg</file>
<file alias="JoystickBezel.png">../resources/JoystickBezel.png</file>
<file alias="JoystickBezelLight.png">../resources/JoystickBezelLight.png</file>
<file alias="land.svg">../resources/land.svg</file>
<file alias="LockClosed.svg">../resources/LockClosed.svg</file>
<file alias="LockOpen.svg">../resources/LockOpen.svg</file>
<file alias="notile.png">../resources/notile.png</file>
<file alias="Pause.svg">../resources/Pause.svg</file>
<file alias="pause-mission.svg">../resources/pause-mission.svg</file>
<file alias="Play">../resources/Play.svg</file>
<file alias="PowerButton">../resources/PowerButton.svg</file>
<file alias="QGCLogoBlack">../resources/QGCLogoBlack.svg</file>
<file alias="QGCLogoFull">../resources/QGCLogoFull.svg</file>
<file alias="QGCLogoWhite">../resources/QGCLogoWhite.svg</file>
<file alias="QGCLogoArrow">../resources/QGCLogoArrow.svg</file>
<file alias="QGroundControlConnect">../resources/QGroundControlConnect.svg</file>
<file alias="rtl.svg">../resources/rtl.svg</file>
<file alias="SplashScreen">../resources/SplashScreen.png</file>
<file alias="Stop">../resources/Stop.svg</file>
<file alias="takeoff.svg">../resources/takeoff.svg</file>
<file alias="TrashDelete.svg">../resources/TrashDelete.svg</file>
<file alias="waves.svg">../resources/waves.svg</file>
<file alias="wind-guru.svg">../resources/wind-guru.svg</file>
<file alias="wind-rose.svg">../resources/wind-rose.svg</file>
<file alias="wind-roseBlack.svg">../resources/wind-roseBlack.svg</file>
<file alias="wind-rose-arrow.svg">../resources/wind-rose-arrow.svg</file>
<file alias="XDelete.svg">../resources/XDelete.svg</file>
<file alias="XDeleteBlack.svg">../resources/XDeleteBlack.svg</file>
<file alias="waypoint.svg">../resources/waypoint.svg</file>
<file>../resources/icons/qgroundcontrol.ico</file>
</qresource>
<qresource prefix="/res/firmware">
<file alias="3drradio.png">../resources/firmware/3drradio.png</file>
<file alias="apm.png">../resources/firmware/apm.png</file>
<file alias="px4.png">../resources/firmware/px4.png</file>
</qresource>
<qresource prefix="/res/calibration">
<file alias="accel_back.png">../resources/calibration/accel_back.png</file>
<file alias="accel_down.png">../resources/calibration/accel_down.png</file>
<file alias="accel_front.png">../resources/calibration/accel_front.png</file>
<file alias="accel_left.png">../resources/calibration/accel_left.png</file>
<file alias="accel_right.png">../resources/calibration/accel_right.png</file>
<file alias="accel_up.png">../resources/calibration/accel_up.png</file>
</qresource>
<qresource prefix="/qml/calibration/mode1">
<file alias="radioCenter.png">../resources/calibration/mode1/radioCenter.png</file>
<file alias="radioHome.png">../resources/calibration/mode1/radioHome.png</file>
<file alias="radioPitchDown.png">../resources/calibration/mode1/radioPitchDown.png</file>
<file alias="radioPitchUp.png">../resources/calibration/mode1/radioPitchUp.png</file>
<file alias="radioRollLeft.png">../resources/calibration/mode1/radioRollLeft.png</file>
<file alias="radioRollRight.png">../resources/calibration/mode1/radioRollRight.png</file>
<file alias="radioSwitchMinMax.png">../resources/calibration/mode1/radioSwitchMinMax.png</file>
<file alias="radioThrottleDown.png">../resources/calibration/mode1/radioThrottleDown.png</file>
<file alias="radioThrottleUp.png">../resources/calibration/mode1/radioThrottleUp.png</file>
<file alias="radioYawLeft.png">../resources/calibration/mode1/radioYawLeft.png</file>
<file alias="radioYawRight.png">../resources/calibration/mode1/radioYawRight.png</file>
</qresource>
<qresource prefix="/qml/calibration/mode2">
<file alias="radioCenter.png">../resources/calibration/mode2/radioCenter.png</file>
<file alias="radioHome.png">../resources/calibration/mode2/radioHome.png</file>
<file alias="radioPitchDown.png">../resources/calibration/mode2/radioPitchDown.png</file>
<file alias="radioPitchUp.png">../resources/calibration/mode2/radioPitchUp.png</file>
<file alias="radioRollLeft.png">../resources/calibration/mode2/radioRollLeft.png</file>
<file alias="radioRollRight.png">../resources/calibration/mode2/radioRollRight.png</file>
<file alias="radioSwitchMinMax.png">../resources/calibration/mode2/radioSwitchMinMax.png</file>
<file alias="radioThrottleDown.png">../resources/calibration/mode2/radioThrottleDown.png</file>
<file alias="radioThrottleUp.png">../resources/calibration/mode2/radioThrottleUp.png</file>
<file alias="radioYawLeft.png">../resources/calibration/mode2/radioYawLeft.png</file>
<file alias="radioYawRight.png">../resources/calibration/mode2/radioYawRight.png</file>
</qresource>
<qresource prefix="/db/mapping/joystick">
<file alias="gamecontrollerdb.txt">../resources/SDL_GameControllerDB/gamecontrollerdb.txt</file>
</qresource>
<qresource prefix="/res/audio">
<file alias="Alert">../resources/audio/alert.wav</file>
</qresource>
<qresource prefix="/opengl">
<file>../resources/opengl/buglist.json</file>
</qresource>
</RCC>
<RCC>
<qresource prefix="/unittest">
<file alias="FactSystemTest.qml">../src/FactSystem/FactSystemTest.qml</file>
</qresource>
<qresource prefix="/toolbar">
<file alias="ArmedIndicator.qml">../src/ui/toolbar/ArmedIndicator.qml</file>
<file alias="BatteryIndicator.qml">../src/ui/toolbar/BatteryIndicator.qml</file>
<file alias="GPSIndicator.qml">../src/ui/toolbar/GPSIndicator.qml</file>
<file alias="GPSRTKIndicator.qml">../src/ui/toolbar/GPSRTKIndicator.qml</file>
<file alias="JoystickIndicator.qml">../src/ui/toolbar/JoystickIndicator.qml</file>
<file alias="LinkIndicator.qml">../src/ui/toolbar/LinkIndicator.qml</file>
<file alias="MainToolBar.qml">../src/ui/toolbar/MainToolBar.qml</file>
<file alias="MainToolBarIndicators.qml">../src/ui/toolbar/MainToolBarIndicators.qml</file>
<file alias="MessageIndicator.qml">../src/ui/toolbar/MessageIndicator.qml</file>
<file alias="ModeIndicator.qml">../src/ui/toolbar/ModeIndicator.qml</file>
<file alias="MultiVehicleSelector.qml">../src/ui/toolbar/MultiVehicleSelector.qml</file>
<file alias="RCRSSIIndicator.qml">../src/ui/toolbar/RCRSSIIndicator.qml</file>
<file alias="ROIIndicator.qml">../src/ui/toolbar/ROIIndicator.qml</file>
<file alias="TelemetryRSSIIndicator.qml">../src/ui/toolbar/TelemetryRSSIIndicator.qml</file>
<file alias="VTOLModeIndicator.qml">../src/ui/toolbar/VTOLModeIndicator.qml</file>
</qresource>
<qresource prefix="/checklists">
<file alias="DefaultChecklist.qml">../src/FlightDisplay/DefaultChecklist.qml</file>
<file alias="MultiRotorChecklist.qml">../src/FlightDisplay/MultiRotorChecklist.qml</file>
<file alias="FixedWingChecklist.qml">../src/FlightDisplay/FixedWingChecklist.qml</file>
<file alias="VTOLChecklist.qml">../src/FlightDisplay/VTOLChecklist.qml</file>
<file alias="RoverChecklist.qml">../src/FlightDisplay/RoverChecklist.qml</file>
<file alias="SubChecklist.qml">../src/FlightDisplay/SubChecklist.qml</file>
</qresource>
<qresource prefix="/qml">
<file alias="QGroundControl/Controls/HeightIndicator.qml">../src/QmlControls/HeightIndicator.qml</file>
<file alias="QGroundControl/Controls/QGCDynamicObjectManager.qml">../src/QmlControls/QGCDynamicObjectManager.qml</file>
<file alias="QGroundControl/Controls/QGCOptionsComboBox.qml">../src/QmlControls/QGCOptionsComboBox.qml</file>
<file alias="QGroundControl/Controls/TransectStyleMapVisuals.qml">../src/PlanView/TransectStyleMapVisuals.qml</file>
<file alias="QGroundControl/FlightMap/MapLineArrow.qml">../src/MissionManager/MapLineArrow.qml</file>
<file alias="QGroundControl/FlightMap/SplitIndicator.qml">../src/FlightMap/MapItems/SplitIndicator.qml</file>
<file alias="AnalyzeView.qml">../src/AnalyzeView/AnalyzeView.qml</file>
<file alias="AppSettings.qml">../src/ui/AppSettings.qml</file>
<file alias="BluetoothSettings.qml">../src/ui/preferences/BluetoothSettings.qml</file>
<file alias="CameraPageWidget.qml">../src/FlightMap/Widgets/CameraPageWidget.qml</file>
<file alias="CorridorScanEditor.qml">../src/PlanView/CorridorScanEditor.qml</file>
<file alias="CustomCommandWidget.qml">../src/ViewWidgets/CustomCommandWidget.qml</file>
<file alias="DebugWindow.qml">../src/ui/preferences/DebugWindow.qml</file>
<file alias="ESP8266Component.qml">../src/AutoPilotPlugins/Common/ESP8266Component.qml</file>
<file alias="ESP8266ComponentSummary.qml">../src/AutoPilotPlugins/Common/ESP8266ComponentSummary.qml</file>
<file alias="ExitWithErrorWindow.qml">../src/ui/ExitWithErrorWindow.qml</file>
<file alias="FirmwareUpgrade.qml">../src/VehicleSetup/FirmwareUpgrade.qml</file>
<file alias="FlightDisplayViewDummy.qml">../src/FlightDisplay/FlightDisplayViewDummy.qml</file>
<file alias="FlightDisplayViewUVC.qml">../src/FlightDisplay/FlightDisplayViewUVC.qml</file>
<file alias="FWLandingPatternEditor.qml">../src/PlanView/FWLandingPatternEditor.qml</file>
<file alias="GeneralSettings.qml">../src/ui/preferences/GeneralSettings.qml</file>
<file alias="GeoTagPage.qml">../src/AnalyzeView/GeoTagPage.qml</file>
<file alias="HealthPageWidget.qml">../src/FlightMap/Widgets/HealthPageWidget.qml</file>
<file alias="HelpSettings.qml">../src/ui/preferences/HelpSettings.qml</file>
<file alias="JoystickConfig.qml">../src/VehicleSetup/JoystickConfig.qml</file>
<file alias="JoystickConfigAdvanced.qml">../src/VehicleSetup/JoystickConfigAdvanced.qml</file>
<file alias="JoystickConfigButtons.qml">../src/VehicleSetup/JoystickConfigButtons.qml</file>
<file alias="JoystickConfigCalibration.qml">../src/VehicleSetup/JoystickConfigCalibration.qml</file>
<file alias="JoystickConfigGeneral.qml">../src/VehicleSetup/JoystickConfigGeneral.qml</file>
<file alias="LinkSettings.qml">../src/ui/preferences/LinkSettings.qml</file>
<file alias="LogDownloadPage.qml">../src/AnalyzeView/LogDownloadPage.qml</file>
<file alias="LogReplaySettings.qml">../src/ui/preferences/LogReplaySettings.qml</file>
<file alias="MainRootWindow.qml">../src/ui/MainRootWindow.qml</file>
<file alias="MavlinkConsolePage.qml">../src/AnalyzeView/MavlinkConsolePage.qml</file>
<file alias="MAVLinkInspectorPage.qml">../src/AnalyzeView/MAVLinkInspectorPage.qml</file>
<file alias="MavlinkSettings.qml">../src/ui/preferences/MavlinkSettings.qml</file>
<file alias="MicrohardSettings.qml">../src/Microhard/MicrohardSettings.qml</file>
<file alias="MissionSettingsEditor.qml">../src/PlanView/MissionSettingsEditor.qml</file>
<file alias="MockLink.qml">../src/ui/preferences/MockLink.qml</file>
<file alias="MockLinkSettings.qml">../src/ui/preferences/MockLinkSettings.qml</file>
<file alias="MotorComponent.qml">../src/AutoPilotPlugins/Common/MotorComponent.qml</file>
<file alias="OfflineMap.qml">../src/QtLocationPlugin/QMLControl/OfflineMap.qml</file>
<file alias="PlanToolBar.qml">../src/PlanView/PlanToolBar.qml</file>
<file alias="PlanToolBarIndicators.qml">../src/PlanView/PlanToolBarIndicators.qml</file>
<file alias="PlanView.qml">../src/PlanView/PlanView.qml</file>
<file alias="PreFlightCheckList.qml">../src/FlightDisplay/PreFlightCheckList.qml</file>
<file alias="PX4FlowSensor.qml">../src/VehicleSetup/PX4FlowSensor.qml</file>
<file alias="QGCInstrumentWidget.qml">../src/FlightMap/Widgets/QGCInstrumentWidget.qml</file>
<file alias="QGCInstrumentWidgetAlternate.qml">../src/FlightMap/Widgets/QGCInstrumentWidgetAlternate.qml</file>
<file alias="QGCViewDialogContainer.qml">../src/QmlControls/QGCViewDialogContainer.qml</file>
<file alias="QGroundControl/Controls/AnalyzePage.qml">../src/AnalyzeView/AnalyzePage.qml</file>
<file alias="QGroundControl/Controls/AppMessages.qml">../src/QmlControls/AppMessages.qml</file>
<file alias="QGroundControl/Controls/AxisMonitor.qml">../src/QmlControls/AxisMonitor.qml</file>
<file alias="QGroundControl/Controls/CameraCalcCamera.qml">../src/PlanView/CameraCalcCamera.qml</file>
<file alias="QGroundControl/Controls/CameraCalcGrid.qml">../src/PlanView/CameraCalcGrid.qml</file>
<file alias="QGroundControl/Controls/CameraSection.qml">../src/PlanView/CameraSection.qml</file>
<file alias="QGroundControl/Controls/ClickableColor.qml">../src/QmlControls/ClickableColor.qml</file>
<file alias="QGroundControl/Controls/CorridorScanMapVisual.qml">../src/PlanView/CorridorScanMapVisual.qml</file>
<file alias="QGroundControl/Controls/DeadMouseArea.qml">../src/QmlControls/DeadMouseArea.qml</file>
<file alias="QGroundControl/Controls/DropButton.qml">../src/QmlControls/DropButton.qml</file>
<file alias="QGroundControl/Controls/DropPanel.qml">../src/QmlControls/DropPanel.qml</file>
<file alias="QGroundControl/Controls/EditPositionDialog.qml">../src/QmlControls/EditPositionDialog.qml</file>
<file alias="QGroundControl/Controls/ExclusiveGroupItem.qml">../src/QmlControls/ExclusiveGroupItem.qml</file>
<file alias="QGroundControl/Controls/FactSliderPanel.qml">../src/QmlControls/FactSliderPanel.qml</file>
<file alias="QGroundControl/Controls/FileButton.qml">../src/QmlControls/FileButton.qml</file>
<file alias="QGroundControl/Controls/FlightModeDropdown.qml">../src/QmlControls/FlightModeDropdown.qml</file>
<file alias="QGroundControl/Controls/FlightModeMenu.qml">../src/QmlControls/FlightModeMenu.qml</file>
<file alias="QGroundControl/Controls/FWLandingPatternMapVisual.qml">../src/PlanView/FWLandingPatternMapVisual.qml</file>
<file alias="QGroundControl/Controls/GeoFenceEditor.qml">../src/PlanView/GeoFenceEditor.qml</file>
<file alias="QGroundControl/Controls/GeoFenceMapVisuals.qml">../src/PlanView/GeoFenceMapVisuals.qml</file>
<file alias="QGroundControl/Controls/IndicatorButton.qml">../src/QmlControls/IndicatorButton.qml</file>
<file alias="QGroundControl/Controls/InstrumentValue.qml">../src/QmlControls/InstrumentValue.qml</file>
<file alias="QGroundControl/Controls/InstrumentValueArea.qml">../src/QmlControls/InstrumentValueArea.qml</file>
<file alias="QGroundControl/Controls/InstrumentValueEditDialog.qml">../src/QmlControls/InstrumentValueEditDialog.qml</file>
<file alias="QGroundControl/Controls/JoystickThumbPad.qml">../src/QmlControls/JoystickThumbPad.qml</file>
<file alias="QGroundControl/Controls/KMLOrSHPFileDialog.qml">../src/QmlControls/KMLOrSHPFileDialog.qml</file>
<file alias="QGroundControl/Controls/LogReplayStatusBar.qml">../src/QmlControls/LogReplayStatusBar.qml</file>
<file alias="QGroundControl/Controls/MainWindowSavedState.qml">../src/QmlControls/MainWindowSavedState.qml</file>
<file alias="QGroundControl/Controls/MAVLinkChart.qml">../src/QmlControls/MAVLinkChart.qml</file>
<file alias="QGroundControl/Controls/MAVLinkMessageButton.qml">../src/QmlControls/MAVLinkMessageButton.qml</file>
<file alias="QGroundControl/Controls/MissionCommandDialog.qml">../src/QmlControls/MissionCommandDialog.qml</file>
<file alias="QGroundControl/Controls/MissionItemEditor.qml">../src/PlanView/MissionItemEditor.qml</file>
<file alias="QGroundControl/Controls/MissionItemIndexLabel.qml">../src/QmlControls/MissionItemIndexLabel.qml</file>
<file alias="QGroundControl/Controls/MissionItemMapVisual.qml">../src/PlanView/MissionItemMapVisual.qml</file>
<file alias="QGroundControl/Controls/MissionItemStatus.qml">../src/PlanView/MissionItemStatus.qml</file>
<file alias="QGroundControl/Controls/ModeSwitchDisplay.qml">../src/QmlControls/ModeSwitchDisplay.qml</file>
<file alias="QGroundControl/Controls/MultiRotorMotorDisplay.qml">../src/QmlControls/MultiRotorMotorDisplay.qml</file>
<file alias="QGroundControl/Controls/OfflineMapButton.qml">../src/QmlControls/OfflineMapButton.qml</file>
<file alias="QGroundControl/Controls/PageView.qml">../src/QmlControls/PageView.qml</file>
<file alias="QGroundControl/Controls/ParameterEditor.qml">../src/QmlControls/ParameterEditor.qml</file>
<file alias="QGroundControl/Controls/ParameterEditorDialog.qml">../src/QmlControls/ParameterEditorDialog.qml</file>
<file alias="QGroundControl/Controls/PIDTuning.qml">../src/QmlControls/PIDTuning.qml</file>
<file alias="QGroundControl/Controls/PlanEditToolbar.qml">../src/PlanView/PlanEditToolbar.qml</file>
<file alias="QGroundControl/Controls/PreFlightCheckButton.qml">../src/QmlControls/PreFlightCheckButton.qml</file>
<file alias="QGroundControl/Controls/PreFlightCheckGroup.qml">../src/QmlControls/PreFlightCheckGroup.qml</file>
<file alias="QGroundControl/Controls/PreFlightCheckModel.qml">../src/QmlControls/PreFlightCheckModel.qml</file>
<file alias="QGroundControl/Controls/QGCButton.qml">../src/QmlControls/QGCButton.qml</file>
<file alias="QGroundControl/Controls/QGCCheckBox.qml">../src/QmlControls/QGCCheckBox.qml</file>
<file alias="QGroundControl/Controls/QGCColoredImage.qml">../src/QmlControls/QGCColoredImage.qml</file>
<file alias="QGroundControl/Controls/QGCComboBox.qml">../src/QmlControls/QGCComboBox.qml</file>
<file alias="QGroundControl/Controls/QGCFileDialog.qml">../src/QmlControls/QGCFileDialog.qml</file>
<file alias="QGroundControl/Controls/QGCFlickable.qml">../src/QmlControls/QGCFlickable.qml</file>
<file alias="QGroundControl/Controls/QGCFlickableHorizontalIndicator.qml">../src/QmlControls/QGCFlickableHorizontalIndicator.qml</file>
<file alias="QGroundControl/Controls/QGCFlickableVerticalIndicator.qml">../src/QmlControls/QGCFlickableVerticalIndicator.qml</file>
<file alias="QGroundControl/Controls/QGCGroupBox.qml">../src/QmlControls/QGCGroupBox.qml</file>
<file alias="QGroundControl/Controls/QGCHoverButton.qml">../src/QmlControls/QGCHoverButton.qml</file>
<file alias="QGroundControl/Controls/QGCLabel.qml">../src/QmlControls/QGCLabel.qml</file>
<file alias="QGroundControl/Controls/QGCListView.qml">../src/QmlControls/QGCListView.qml</file>
<file alias="QGroundControl/Controls/QGCMapCircleVisuals.qml">../src/MissionManager/QGCMapCircleVisuals.qml</file>
<file alias="QGroundControl/Controls/QGCMapLabel.qml">../src/QmlControls/QGCMapLabel.qml</file>
<file alias="QGroundControl/Controls/QGCMapPolygonVisuals.qml">../src/MissionManager/QGCMapPolygonVisuals.qml</file>
<file alias="QGroundControl/Controls/QGCMapPolylineVisuals.qml">../src/MissionManager/QGCMapPolylineVisuals.qml</file>
<file alias="QGroundControl/Controls/QGCMenu.qml">../src/QmlControls/QGCMenu.qml</file>
<file alias="QGroundControl/Controls/QGCMenuItem.qml">../src/QmlControls/QGCMenuItem.qml</file>
<file alias="QGroundControl/Controls/QGCMenuSeparator.qml">../src/QmlControls/QGCMenuSeparator.qml</file>
<file alias="QGroundControl/Controls/QGCMouseArea.qml">../src/QmlControls/QGCMouseArea.qml</file>
<file alias="QGroundControl/Controls/QGCMovableItem.qml">../src/QmlControls/QGCMovableItem.qml</file>
<file alias="QGroundControl/Controls/QGCPopupDialog.qml">../src/QmlControls/QGCPopupDialog.qml</file>
<file alias="QGroundControl/Controls/QGCPopupDialogContainer.qml">../src/QmlControls/QGCPopupDialogContainer.qml</file>
<file alias="QGroundControl/Controls/QGCPipable.qml">../src/QmlControls/QGCPipable.qml</file>
<file alias="QGroundControl/Controls/QGCRadioButton.qml">../src/QmlControls/QGCRadioButton.qml</file>
<file alias="QGroundControl/Controls/QGCSlider.qml">../src/QmlControls/QGCSlider.qml</file>
<file alias="QGroundControl/Controls/QGCSwitch.qml">../src/QmlControls/QGCSwitch.qml</file>
<file alias="QGroundControl/Controls/QGCTabBar.qml">../src/QmlControls/QGCTabBar.qml</file>
<file alias="QGroundControl/Controls/QGCTabButton.qml">../src/QmlControls/QGCTabButton.qml</file>
<file alias="QGroundControl/Controls/QGCTextField.qml">../src/QmlControls/QGCTextField.qml</file>
<file alias="QGroundControl/Controls/QGCToolBarButton.qml">../src/QmlControls/QGCToolBarButton.qml</file>
<file alias="QGroundControl/Controls/QGCViewDialog.qml">../src/QmlControls/QGCViewDialog.qml</file>
<file alias="QGroundControl/Controls/QGCViewMessage.qml">../src/QmlControls/QGCViewMessage.qml</file>
<file alias="QGroundControl/Controls/qmldir">../src/QmlControls/QGroundControl/Controls/qmldir</file>
<file alias="QGroundControl/Controls/RallyPointEditorHeader.qml">../src/PlanView/RallyPointEditorHeader.qml</file>
<file alias="QGroundControl/Controls/RallyPointItemEditor.qml">../src/PlanView/RallyPointItemEditor.qml</file>
<file alias="QGroundControl/Controls/RallyPointMapVisuals.qml">../src/PlanView/RallyPointMapVisuals.qml</file>
<file alias="QGroundControl/Controls/RCChannelMonitor.qml">../src/QmlControls/RCChannelMonitor.qml</file>
<file alias="QGroundControl/Controls/RCToParamDialog.qml">../src/QmlControls/RCToParamDialog.qml</file>
<file alias="QGroundControl/Controls/RoundButton.qml">../src/QmlControls/RoundButton.qml</file>
<file alias="QGroundControl/Controls/SectionHeader.qml">../src/QmlControls/SectionHeader.qml</file>
<file alias="QGroundControl/Controls/SetupPage.qml">../src/AutoPilotPlugins/Common/SetupPage.qml</file>
<file alias="QGroundControl/Controls/SignalStrength.qml">../src/ui/toolbar/SignalStrength.qml</file>
<file alias="QGroundControl/Controls/SimpleItemMapVisual.qml">../src/PlanView/SimpleItemMapVisual.qml</file>
<file alias="QGroundControl/Controls/SliderSwitch.qml">../src/QmlControls/SliderSwitch.qml</file>
<file alias="QGroundControl/Controls/StructureScanMapVisual.qml">../src/PlanView/StructureScanMapVisual.qml</file>
<file alias="QGroundControl/Controls/SubMenuButton.qml">../src/QmlControls/SubMenuButton.qml</file>
<file alias="QGroundControl/Controls/SurveyMapVisual.qml">../src/PlanView/SurveyMapVisual.qml</file>
<file alias="QGroundControl/Controls/TerrainStatus.qml">../src/PlanView/TerrainStatus.qml</file>
<file alias="QGroundControl/Controls/TakeoffItemMapVisual.qml">../src/PlanView/TakeoffItemMapVisual.qml</file>
<file alias="QGroundControl/Controls/ToolStrip.qml">../src/QmlControls/ToolStrip.qml</file>
<file alias="QGroundControl/Controls/TransectStyleComplexItemStats.qml">../src/PlanView/TransectStyleComplexItemStats.qml</file>
<file alias="QGroundControl/Controls/VehicleRotationCal.qml">../src/QmlControls/VehicleRotationCal.qml</file>
<file alias="QGroundControl/Controls/VehicleSummaryRow.qml">../src/QmlControls/VehicleSummaryRow.qml</file>
<file alias="QGroundControl/Controls/ViewWidget.qml">../src/ViewWidgets/ViewWidget.qml</file>
<file alias="QGroundControl/FactControls/AltitudeFactTextField.qml">../src/FactSystem/FactControls/AltitudeFactTextField.qml</file>
<file alias="QGroundControl/FactControls/FactBitmask.qml">../src/FactSystem/FactControls/FactBitmask.qml</file>
<file alias="QGroundControl/FactControls/FactCheckBox.qml">../src/FactSystem/FactControls/FactCheckBox.qml</file>
<file alias="QGroundControl/FactControls/FactComboBox.qml">../src/FactSystem/FactControls/FactComboBox.qml</file>
<file alias="QGroundControl/FactControls/FactLabel.qml">../src/FactSystem/FactControls/FactLabel.qml</file>
<file alias="QGroundControl/FactControls/FactTextField.qml">../src/FactSystem/FactControls/FactTextField.qml</file>
<file alias="QGroundControl/FactControls/FactTextFieldGrid.qml">../src/FactSystem/FactControls/FactTextFieldGrid.qml</file>
<file alias="QGroundControl/FactControls/FactTextFieldRow.qml">../src/FactSystem/FactControls/FactTextFieldRow.qml</file>
<file alias="QGroundControl/FactControls/FactTextFieldSlider.qml">../src/FactSystem/FactControls/FactTextFieldSlider.qml</file>
<file alias="QGroundControl/FactControls/FactValueSlider.qml">../src/FactSystem/FactControls/FactValueSlider.qml</file>
<file alias="QGroundControl/FactControls/qmldir">../src/QmlControls/QGroundControl/FactControls/qmldir</file>
<file alias="QGroundControl/FlightDisplay/FlightDisplayView.qml">../src/FlightDisplay/FlightDisplayView.qml</file>
<file alias="QGroundControl/FlightDisplay/FlightDisplayViewMap.qml">../src/FlightDisplay/FlightDisplayViewMap.qml</file>
<file alias="QGroundControl/FlightDisplay/FlightDisplayViewVideo.qml">../src/FlightDisplay/FlightDisplayViewVideo.qml</file>
<file alias="QGroundControl/FlightDisplay/FlightDisplayViewWidgets.qml">../src/FlightDisplay/FlightDisplayViewWidgets.qml</file>
<file alias="QGroundControl/FlightDisplay/GuidedActionConfirm.qml">../src/FlightDisplay/GuidedActionConfirm.qml</file>
<file alias="QGroundControl/FlightDisplay/GuidedActionList.qml">../src/FlightDisplay/GuidedActionList.qml</file>
<file alias="QGroundControl/FlightDisplay/GuidedActionsController.qml">../src/FlightDisplay/GuidedActionsController.qml</file>
<file alias="QGroundControl/FlightDisplay/GuidedAltitudeSlider.qml">../src/FlightDisplay/GuidedAltitudeSlider.qml</file>
<file alias="QGroundControl/FlightDisplay/MultiVehicleList.qml">../src/FlightDisplay/MultiVehicleList.qml</file>
<file alias="QGroundControl/FlightDisplay/PreFlightBatteryCheck.qml">../src/FlightDisplay/PreFlightBatteryCheck.qml</file>
<file alias="QGroundControl/FlightDisplay/PreFlightGPSCheck.qml">../src/FlightDisplay/PreFlightGPSCheck.qml</file>
<file alias="QGroundControl/FlightDisplay/PreFlightRCCheck.qml">../src/FlightDisplay/PreFlightRCCheck.qml</file>
<file alias="QGroundControl/FlightDisplay/PreFlightSensorsHealthCheck.qml">../src/FlightDisplay/PreFlightSensorsHealthCheck.qml</file>
<file alias="QGroundControl/FlightDisplay/PreFlightSoundCheck.qml">../src/FlightDisplay/PreFlightSoundCheck.qml</file>
<file alias="QGroundControl/FlightDisplay/TerrainProgress.qml">../src/FlightDisplay/TerrainProgress.qml</file>
<file alias="QGroundControl/FlightDisplay/qmldir">../src/QmlControls/QGroundControl/FlightDisplay/qmldir</file>
<file alias="QGroundControl/FlightMap/CameraTriggerIndicator.qml">../src/FlightMap/MapItems/CameraTriggerIndicator.qml</file>
<file alias="QGroundControl/FlightMap/CenterMapDropButton.qml">../src/FlightMap/Widgets/CenterMapDropButton.qml</file>
<file alias="QGroundControl/FlightMap/CenterMapDropPanel.qml">../src/FlightMap/Widgets/CenterMapDropPanel.qml</file>
<file alias="QGroundControl/FlightMap/CompassRing.qml">../src/FlightMap/Widgets/CompassRing.qml</file>
<file alias="QGroundControl/FlightMap/CustomMapItems.qml">../src/FlightMap/MapItems/CustomMapItems.qml</file>
<file alias="QGroundControl/FlightMap/FlightMap.qml">../src/FlightMap/FlightMap.qml</file>
<file alias="QGroundControl/FlightMap/InstrumentSwipeView.qml">../src/FlightMap/Widgets/InstrumentSwipeView.qml</file>
<file alias="QGroundControl/FlightMap/MapFitFunctions.qml">../src/FlightMap/Widgets/MapFitFunctions.qml</file>
<file alias="QGroundControl/FlightMap/MapScale.qml">../src/FlightMap/MapScale.qml</file>
<file alias="QGroundControl/FlightMap/MissionItemIndicator.qml">../src/FlightMap/MapItems/MissionItemIndicator.qml</file>
<file alias="QGroundControl/FlightMap/MissionItemIndicatorDrag.qml">../src/FlightMap/MapItems/MissionItemIndicatorDrag.qml</file>
<file alias="QGroundControl/FlightMap/MissionItemView.qml">../src/FlightMap/MapItems/MissionItemView.qml</file>
<file alias="QGroundControl/FlightMap/MissionLineView.qml">../src/FlightMap/MapItems/MissionLineView.qml</file>
<file alias="QGroundControl/FlightMap/PlanMapItems.qml">../src/FlightMap/MapItems/PlanMapItems.qml</file>
<file alias="QGroundControl/FlightMap/PolygonEditor.qml">../src/FlightMap/MapItems/PolygonEditor.qml</file>
<file alias="QGroundControl/FlightMap/QGCArtificialHorizon.qml">../src/FlightMap/Widgets/QGCArtificialHorizon.qml</file>
<file alias="QGroundControl/FlightMap/QGCAttitudeHUD.qml">../src/FlightMap/Widgets/QGCAttitudeHUD.qml</file>
<file alias="QGroundControl/FlightMap/QGCAttitudeWidget.qml">../src/FlightMap/Widgets/QGCAttitudeWidget.qml</file>
<file alias="QGroundControl/FlightMap/QGCCompassWidget.qml">../src/FlightMap/Widgets/QGCCompassWidget.qml</file>
<file alias="QGroundControl/FlightMap/QGCPitchIndicator.qml">../src/FlightMap/Widgets/QGCPitchIndicator.qml</file>
<file alias="QGroundControl/FlightMap/QGCVideoBackground.qml">../src/FlightMap/QGCVideoBackground.qml</file>
<file alias="QGroundControl/FlightMap/qmldir">../src/QmlControls/QGroundControl/FlightMap/qmldir</file>
<file alias="QGroundControl/FlightMap/VehicleMapItem.qml">../src/FlightMap/MapItems/VehicleMapItem.qml</file>
<file alias="QGroundControl/ScreenTools/qmldir">../src/QmlControls/QGroundControl/ScreenTools/qmldir</file>
<file alias="QGroundControl/ScreenTools/ScreenTools.qml">../src/QmlControls/ScreenTools.qml</file>
<file alias="QmlTest.qml">../src/QmlControls/QmlTest.qml</file>
<file alias="RadioComponent.qml">../src/AutoPilotPlugins/Common/RadioComponent.qml</file>
<file alias="SerialSettings.qml">../src/ui/preferences/SerialSettings.qml</file>
<file alias="SetupParameterEditor.qml">../src/VehicleSetup/SetupParameterEditor.qml</file>
<file alias="SetupView.qml">../src/VehicleSetup/SetupView.qml</file>
<file alias="SimpleItemEditor.qml">../src/PlanView/SimpleItemEditor.qml</file>
<file alias="StructureScanEditor.qml">../src/PlanView/StructureScanEditor.qml</file>
<file alias="SurveyItemEditor.qml">../src/PlanView/SurveyItemEditor.qml</file>
<file alias="SyslinkComponent.qml">../src/AutoPilotPlugins/Common/SyslinkComponent.qml</file>
<file alias="TaisyncSettings.qml">../src/Taisync/TaisyncSettings.qml</file>
<file alias="TcpSettings.qml">../src/ui/preferences/TcpSettings.qml</file>
<file alias="test.qml">../src/test.qml</file>
<file alias="UdpSettings.qml">../src/ui/preferences/UdpSettings.qml</file>
<file alias="ValuePageWidget.qml">../src/FlightMap/Widgets/ValuePageWidget.qml</file>
<file alias="VehicleSummary.qml">../src/VehicleSetup/VehicleSummary.qml</file>
<file alias="VibrationPageWidget.qml">../src/FlightMap/Widgets/VibrationPageWidget.qml</file>
<file alias="VideoPageWidget.qml">../src/FlightMap/Widgets/VideoPageWidget.qml</file>
<file alias="VirtualJoystick.qml">../src/FlightDisplay/VirtualJoystick.qml</file>
<file alias="QGroundControl/Controls/VTOLLandingPatternMapVisual.qml">../src/PlanView/VTOLLandingPatternMapVisual.qml</file>
<file alias="VTOLLandingPatternEditor.qml">../src/PlanView/VTOLLandingPatternEditor.qml</file>
<file alias="QGroundControl/Specific/qmldir">../src/QmlControls/QGroundControl/Specific/qmldir</file>
<file alias="QGroundControl/Specific/StartupWizard.qml">../src/QmlControls/QGroundControl/Specific/StartupWizard.qml</file>
<file alias="QGroundControl/Specific/BaseStartupWizardPage.qml">../src/QmlControls/QGroundControl/Specific/BaseStartupWizardPage.qml</file>
<file alias="QGroundControl/Specific/UnitsWizardPage.qml">../src/QmlControls/QGroundControl/Specific/UnitsWizardPage.qml</file>
</qresource>
<qresource prefix="/json">
<file alias="ADSBVehicleManager.SettingsGroup.json">../src/Settings/ADSBVehicleManager.SettingsGroup.json</file>
<file alias="APMMavlinkStreamRate.SettingsGroup.json">../src/Settings/APMMavlinkStreamRate.SettingsGroup.json</file>
<file alias="App.SettingsGroup.json">../src/Settings/App.SettingsGroup.json</file>
<file alias="AutoConnect.SettingsGroup.json">../src/Settings/AutoConnect.SettingsGroup.json</file>
<file alias="BrandImage.SettingsGroup.json">../src/Settings/BrandImage.SettingsGroup.json</file>
<file alias="BreachReturn.FactMetaData.json">../src/MissionManager/BreachReturn.FactMetaData.json</file>
<file alias="CameraCalc.FactMetaData.json">../src/MissionManager/CameraCalc.FactMetaData.json</file>
<file alias="CameraSection.FactMetaData.json">../src/MissionManager/CameraSection.FactMetaData.json</file>
<file alias="CameraSpec.FactMetaData.json">../src/MissionManager/CameraSpec.FactMetaData.json</file>
<file alias="CorridorScan.SettingsGroup.json">../src/MissionManager/CorridorScan.SettingsGroup.json</file>
<file alias="EditPositionDialog.FactMetaData.json">../src/QmlControls/EditPositionDialog.FactMetaData.json</file>
<file alias="FirmwareUpgrade.SettingsGroup.json">../src/Settings/FirmwareUpgrade.SettingsGroup.json</file>
<file alias="FlightMap.SettingsGroup.json">../src/Settings/FlightMap.SettingsGroup.json</file>
<file alias="FlyView.SettingsGroup.json">../src/Settings/FlyView.SettingsGroup.json</file>
<file alias="FWLandingPattern.FactMetaData.json">../src/MissionManager/FWLandingPattern.FactMetaData.json</file>
<file alias="MavCmdInfoCommon.json">../src/MissionManager/MavCmdInfoCommon.json</file>
<file alias="MavCmdInfoFixedWing.json">../src/MissionManager/MavCmdInfoFixedWing.json</file>
<file alias="MavCmdInfoMultiRotor.json">../src/MissionManager/MavCmdInfoMultiRotor.json</file>
<file alias="MavCmdInfoRover.json">../src/MissionManager/MavCmdInfoRover.json</file>
<file alias="MavCmdInfoSub.json">../src/MissionManager/MavCmdInfoSub.json</file>
<file alias="MavCmdInfoVTOL.json">../src/MissionManager/MavCmdInfoVTOL.json</file>
<file alias="MissionSettings.FactMetaData.json">../src/MissionManager/MissionSettings.FactMetaData.json</file>
<file alias="OfflineMaps.SettingsGroup.json">../src/Settings/OfflineMaps.SettingsGroup.json</file>
<file alias="PlanView.SettingsGroup.json">../src/Settings/PlanView.SettingsGroup.json</file>
<file alias="QGCMapCircle.Facts.json">../src/MissionManager/QGCMapCircle.Facts.json</file>
<file alias="RallyPoint.FactMetaData.json">../src/MissionManager/RallyPoint.FactMetaData.json</file>
<file alias="RCToParamDialog.FactMetaData.json">../src/QmlControls/RCToParamDialog.FactMetaData.json</file>
<file alias="RTK.SettingsGroup.json">../src/Settings/RTK.SettingsGroup.json</file>
<file alias="SpeedSection.FactMetaData.json">../src/MissionManager/SpeedSection.FactMetaData.json</file>
<file alias="StructureScan.SettingsGroup.json">../src/MissionManager/StructureScan.SettingsGroup.json</file>
<file alias="Survey.SettingsGroup.json">../src/MissionManager/Survey.SettingsGroup.json</file>
<file alias="TransectStyle.SettingsGroup.json">../src/MissionManager/TransectStyle.SettingsGroup.json</file>
<file alias="Units.SettingsGroup.json">../src/Settings/Units.SettingsGroup.json</file>
<file alias="USBBoardInfo.json">../src/comm/USBBoardInfo.json</file>
<file alias="Vehicle/BatteryFact.json">../src/Vehicle/BatteryFact.json</file>
<file alias="Vehicle/ClockFact.json">../src/Vehicle/ClockFact.json</file>
<file alias="Vehicle/DistanceSensorFact.json">../src/Vehicle/DistanceSensorFact.json</file>
<file alias="Vehicle/EstimatorStatusFactGroup.json">../src/Vehicle/EstimatorStatusFactGroup.json</file>
<file alias="Vehicle/GPSFact.json">../src/Vehicle/GPSFact.json</file>
<file alias="Vehicle/GPSRTKFact.json">../src/Vehicle/GPSRTKFact.json</file>
<file alias="Vehicle/SetpointFact.json">../src/Vehicle/SetpointFact.json</file>
<file alias="Vehicle/SubmarineFact.json">../src/Vehicle/SubmarineFact.json</file>
<file alias="Vehicle/TemperatureFact.json">../src/Vehicle/TemperatureFact.json</file>
<file alias="Vehicle/TerrainFactGroup.json">../src/Vehicle/TerrainFactGroup.json</file>
<file alias="Vehicle/VehicleFact.json">../src/Vehicle/VehicleFact.json</file>
<file alias="Vehicle/VibrationFact.json">../src/Vehicle/VibrationFact.json</file>
<file alias="Vehicle/WindFact.json">../src/Vehicle/WindFact.json</file>
<file alias="Video.SettingsGroup.json">../src/Settings/Video.SettingsGroup.json</file>
<file alias="VTOLLandingPattern.FactMetaData.json">../src/MissionManager/VTOLLandingPattern.FactMetaData.json</file>
</qresource>
<qresource prefix="/MockLink">
<file alias="APMArduSubMockLink.params">../src/comm/APMArduSubMockLink.params</file>
<file alias="PX4MockLink.params">../src/comm/PX4MockLink.params</file>
</qresource>
</RCC>
/****************************************************************************
*
* (c) 2009-2019 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.
*
* @file
* @author Gus Grubba <gus@auterion.com>
*/
import QtQuick 2.11
import QtQuick.Controls 2.4
import QtQuick.Layouts 1.11
import QtQuick.Dialogs 1.3
import QtGraphicalEffects 1.0
import QtMultimedia 5.9
import QtPositioning 5.2
import QGroundControl 1.0
import QGroundControl.Controls 1.0
import QGroundControl.FactControls 1.0
import QGroundControl.FactSystem 1.0
import QGroundControl.FlightMap 1.0
import QGroundControl.Palette 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.Vehicle 1.0
import CustomQuickInterface 1.0
import Custom.Widgets 1.0
import Custom.Camera 1.0
Item {
id: _root
height: mainColumn.height
width: mainColumn.width + (ScreenTools.defaultFontPixelWidth * 2)
visible: !QGroundControl.videoManager.fullScreen
readonly property string _commLostStr: qsTr("NO CAMERA")
readonly property real buttonSize: ScreenTools.defaultFontPixelWidth * 5
property real _spacers: ScreenTools.defaultFontPixelHeight * 0.5
property real _labelFieldWidth: ScreenTools.defaultFontPixelWidth * 28
property real _editFieldWidth: ScreenTools.defaultFontPixelWidth * 30
property real _editFieldHeight: ScreenTools.defaultFontPixelHeight * 2
property var _videoManager: QGroundControl.videoManager
property bool _recordingLocalVideo: QGroundControl.videoManager.recording
property var _dynamicCameras: activeVehicle ? activeVehicle.dynamicCameras : null
property bool _isCamera: _dynamicCameras ? _dynamicCameras.cameras.count > 0 : false
property int _curCameraIndex: _dynamicCameras ? _dynamicCameras.currentCamera : 0
property var _camera: _isCamera ? _dynamicCameras.cameras.get(_curCameraIndex) : null
property bool _communicationLost: activeVehicle ? activeVehicle.connectionLost : false
property bool _noSdCard: _camera && _camera.storageTotal === 0
property bool _fullSD: _camera && _camera.storageTotal !== 0 && _camera.storageFree > 0 && _camera.storageFree < 250 // We get kiB from the camera
property bool _cameraVideoMode: !_communicationLost && (_noSdCard ? false : _camera && _camera.cameraMode === QGCCameraControl.CAM_MODE_VIDEO)
property bool _cameraPhotoMode: !_communicationLost && (_noSdCard ? false : _camera && (_camera.cameraMode === QGCCameraControl.CAM_MODE_PHOTO || _camera.cameraMode === QGCCameraControl.CAM_MODE_SURVEY))
property bool _cameraPhotoIdle: !_communicationLost && (_noSdCard ? false : _camera && _camera.photoStatus === QGCCameraControl.PHOTO_CAPTURE_IDLE)
property bool _cameraElapsedMode: !_communicationLost && (_noSdCard ? false : _camera && _camera.cameraMode === QGCCameraControl.CAM_MODE_PHOTO && _camera.photoMode === QGCCameraControl.PHOTO_CAPTURE_TIMELAPSE)
property bool _cameraModeUndefined: !_cameraPhotoMode && !_cameraVideoMode
property bool _recordingVideo: _cameraVideoMode && _camera.videoStatus === QGCCameraControl.VIDEO_CAPTURE_STATUS_RUNNING
property bool _settingsEnabled: !_communicationLost && _camera && _camera.cameraMode !== QGCCameraControl.CAM_MODE_UNDEFINED && _camera.photoStatus === QGCCameraControl.PHOTO_CAPTURE_IDLE && !_recordingVideo
property bool _hasZoom: _camera && _camera.hasZoom
property Fact _irPaletteFact: _camera ? _camera.irPalette : null
property bool _isShortScreen: mainWindow.height / ScreenTools.realPixelDensity < 120
property real _gimbalPitch: activeVehicle ? -activeVehicle.gimbalPitch : 0
property real _gimbalYaw: activeVehicle ? activeVehicle.gimbalYaw : 0
property bool _hasGimbal: activeVehicle && activeVehicle.gimbalData
Connections {
target: QGroundControl.multiVehicleManager.activeVehicle
onConnectionLostChanged: {
if(_communicationLost && cameraSettings.visible) {
cameraSettings.close()
}
}
}
DeadMouseArea {
anchors.fill: parent
}
//-------------------------------------------------------------------------
//-- Main Column
Column {
id: mainColumn
spacing: _spacers
anchors.centerIn: parent
//---------------------------------------------------------------------
//-- Quick Thermal Modes
Item {
id: thermalBackgroundRect
width: buttonsRow.width + (ScreenTools.defaultFontPixelWidth * 4)
height: buttonsRow.height + (ScreenTools.defaultFontPixelHeight)
visible: QGroundControl.videoManager.hasThermal || _irPaletteFact || _camera.vendor === "NextVision"
anchors.horizontalCenter: parent.horizontalCenter
Component.onCompleted: {
if(_irPaletteFact && QGroundControl.videoManager.hasThermal) {
if(_camera.thermalMode === QGCCameraControl.THERMAL_OFF)
standardMode.checked = true
if(_camera.thermalMode === QGCCameraControl.THERMAL_PIP)
thermalPip.checked = true
if(_camera.thermalMode === QGCCameraControl.THERMAL_FULL)
thermalFull.checked = true
}
else
standardMode.checked = true
}
ButtonGroup {
id: buttonGroup
exclusive: true
buttons: buttonsRow.children
}
Row {
id: buttonsRow
spacing: ScreenTools.defaultFontPixelWidth * 0.5
anchors.centerIn: parent
//-- Standard
CustomQuickButton {
id: standardMode
width: buttonSize
height: buttonSize
iconSource: "/custom/img/thermal-standard.svg"
onClicked: {
_camera.thermalMode = QGCCameraControl.THERMAL_OFF
}
}
//-- PIP
CustomQuickButton {
id: thermalPip
width: buttonSize
height: buttonSize
visible: _camera.vendor !== "NextVision"
iconSource: "/custom/img/thermal-pip.svg"
onClicked: {
_camera.thermalMode = QGCCameraControl.THERMAL_PIP
}
}
// Thermal
CustomQuickButton {
id: thermalFull
width: buttonSize
height: buttonSize
iconSource: "/custom/img/thermal-brightness.svg"
onClicked: {
_camera.thermalMode = QGCCameraControl.THERMAL_FULL
}
}
// Thermal palette options
CustomQuickButton {
checkable: false
width: buttonSize
height: buttonSize
visible: _irPaletteFact
iconSource: "/custom/img/thermal-palette.svg"
onClicked: {
thermalPalettes.open()
}
}
}
}
//---------------------------------------------------------------------
//-- Main Camera Control
Row {
spacing: ScreenTools.defaultFontPixelWidth * 0.5
anchors.horizontalCenter: parent.horizontalCenter
Rectangle {
id: cameraRect
height: cameraCol.height
width: cameraCol.width + (ScreenTools.defaultFontPixelWidth * 4)
color: qgcPal.window
radius: ScreenTools.defaultFontPixelWidth * 0.5
Column {
id: cameraCol
spacing: _spacers
anchors.centerIn: parent
Item {
height: 1
width: 1
}
//-----------------------------------------------------------------
//-- Camera Name
QGCLabel {
text: activeVehicle ? (_camera && _camera.modelName !== "" ? _camera.modelName : _commLostStr) : _commLostStr
font.pointSize: ScreenTools.smallFontPointSize
anchors.horizontalCenter: parent.horizontalCenter
}
QGCLabel {
text: {
if(_noSdCard) return qsTr("NONE")
if(_fullSD) return qsTr("FULL")
return _camera ? _camera.storageFreeStr : ""
}
visible: _isShortScreen
color: (_noSdCard || _fullSD) ? qgcPal.colorOrange : qgcPal.text
font.pointSize: ScreenTools.smallFontPointSize
anchors.horizontalCenter: parent.horizontalCenter
}
//-----------------------------------------------------------------
//-- Camera Mode
Item {
width: modeCol.width
height: modeCol.height
anchors.horizontalCenter: parent.horizontalCenter
Column {
id: modeCol
spacing: _spacers
QGCColoredImage {
height: ScreenTools.defaultFontPixelHeight * 1.25
width: height
source: (_cameraModeUndefined || _cameraPhotoMode) ? "/custom/img/camera_photo.svg" : "/custom/img/camera_video.svg"
color: qgcPal.text
fillMode: Image.PreserveAspectFit
sourceSize.height: height
anchors.horizontalCenter: parent.horizontalCenter
}
QGCLabel {
text: _cameraVideoMode ? qsTr("Video") : qsTr("Photo")
font.pointSize: ScreenTools.smallFontPointSize
anchors.horizontalCenter: parent.horizontalCenter
}
}
MouseArea {
anchors.fill: parent
enabled: !_cameraModeUndefined && _camera && _camera.videoStatus !== QGCCameraControl.VIDEO_CAPTURE_STATUS_RUNNING && _cameraPhotoIdle
onClicked: {
_camera.toggleMode()
}
}
}
//-----------------------------------------------------------------
//-- Shutter
Rectangle {
color: Qt.rgba(0,0,0,0)
width: height
height: ScreenTools.defaultFontPixelHeight * 4
radius: width * 0.5
border.color: qgcPal.buttonText
border.width: 1
anchors.horizontalCenter: parent.horizontalCenter
Rectangle {
width: parent.width * 0.85
height: width
radius: width * 0.5
color: _cameraModeUndefined ? qgcPal.colorGrey : ( _cameraVideoMode ? qgcPal.colorRed : qgcPal.text )
visible: !pauseVideo.visible
anchors.centerIn: parent
QGCColoredImage {
id: busyIndicator
height: parent.height * 0.75
width: height
source: "/qmlimages/MapSync.svg"
sourceSize.height: height
fillMode: Image.PreserveAspectFit
mipmap: true
smooth: true
color: qgcPal.window
visible: {
if(_cameraPhotoMode && !_cameraPhotoIdle && !_cameraElapsedMode) {
return true
}
return false
}
anchors.centerIn: parent
RotationAnimation on rotation {
loops: Animation.Infinite
from: 360
to: 0
duration: 740
running: busyIndicator.visible
}
}
QGCLabel {
text: _camera ? _camera.photoLapse.toFixed(0) + 's' : qsTr('N/A')
font.family: ScreenTools.demiboldFontFamily
color: qgcPal.colorBlue
visible: _cameraElapsedMode
anchors.centerIn: parent
}
}
Rectangle {
id: pauseVideo
width: parent.width * 0.5
height: width
color: _cameraModeUndefined ? qgcPal.colorGrey : qgcPal.colorRed
visible: {
if(_cameraVideoMode && _camera.videoStatus === QGCCameraControl.VIDEO_CAPTURE_STATUS_RUNNING) {
return true
}
if(_cameraPhotoMode) {
if(_camera.photoStatus === QGCCameraControl.PHOTO_CAPTURE_INTERVAL_IDLE || _camera.photoStatus === QGCCameraControl.PHOTO_CAPTURE_INTERVAL_IN_PROGRESS) {
return true
}
}
return false
}
anchors.centerIn: parent
}
MouseArea {
anchors.fill: parent
enabled: !_noSdCard
onClicked: {
if(_cameraVideoMode) {
if(_camera.videoStatus === QGCCameraControl.VIDEO_CAPTURE_STATUS_RUNNING) {
_camera.stopVideo()
//-- Local video as well
if (_recordingVideo) {
_videoManager.stopRecording()
}
} else {
if(!_fullSD) {
_camera.startVideo()
}
//-- Local video as well
if(_videoManager) {
_videoManager.startRecording()
}
}
} else {
if(_camera.photoStatus === QGCCameraControl.PHOTO_CAPTURE_INTERVAL_IDLE || _camera.photoStatus === QGCCameraControl.PHOTO_CAPTURE_INTERVAL_IN_PROGRESS) {
_camera.stopTakePhoto()
} else {
if(!_fullSD) {
_camera.takePhoto()
}
}
}
}
}
}
//-----------------------------------------------------------------
//-- Settings
Item {
width: settingsCol.width
height: settingsCol.height
anchors.horizontalCenter: parent.horizontalCenter
Column {
id: settingsCol
spacing: _spacers
anchors.horizontalCenter: parent.horizontalCenter
QGCColoredImage {
width: ScreenTools.defaultFontPixelHeight * 1.25
height: width
sourceSize.width: width
source: "qrc:/custom/img/camera_settings.svg"
color: qgcPal.text
fillMode: Image.PreserveAspectFit
opacity: _settingsEnabled ? 1 : 0.5
anchors.horizontalCenter: parent.horizontalCenter
}
QGCLabel {
text: qsTr("Settings")
font.pointSize: ScreenTools.smallFontPointSize
anchors.horizontalCenter: parent.horizontalCenter
}
}
MouseArea {
anchors.fill: parent
enabled: _settingsEnabled
onClicked: {
cameraSettings.open()
}
}
}
//-----------------------------------------------------------------
//-- microSD Card
Column {
spacing: _spacers
visible: !_isShortScreen
anchors.horizontalCenter: parent.horizontalCenter
QGCColoredImage {
width: ScreenTools.defaultFontPixelHeight * 1.25
height: width
sourceSize.width: width
source: "qrc:/custom/img/microSD.svg"
color: qgcPal.text
fillMode: Image.PreserveAspectFit
opacity: _settingsEnabled ? 1 : 0.5
anchors.horizontalCenter: parent.horizontalCenter
}
QGCLabel {
text: {
if(_noSdCard) return qsTr("NONE")
if(_fullSD) return qsTr("FULL")
return _camera ? _camera.storageFreeStr : ""
}
color: (_noSdCard || _fullSD) ? qgcPal.colorOrange : qgcPal.text
font.pointSize: ScreenTools.smallFontPointSize
anchors.horizontalCenter: parent.horizontalCenter
}
}
//-----------------------------------------------------------------
//-- Recording Time / Images Captured
QGCLabel {
text: (_cameraVideoMode && _camera.videoStatus === QGCCameraControl.VIDEO_CAPTURE_STATUS_RUNNING) ? _camera.recordTimeStr : "00:00:00"
visible: _cameraVideoMode
font.pointSize: ScreenTools.smallFontPointSize
anchors.horizontalCenter: parent.horizontalCenter
}
QGCLabel {
text: activeVehicle && _cameraPhotoMode ? ('00000' + activeVehicle.cameraTriggerPoints.count).slice(-5) : "00000"
visible: _cameraPhotoMode
font.pointSize: ScreenTools.smallFontPointSize
anchors.horizontalCenter: parent.horizontalCenter
}
Item {
height: 1
width: 1
}
}
}
//-- Gimbal Indicator
Rectangle {
id: gimbalBackground
width: _hasGimbal ? ScreenTools.defaultFontPixelWidth * 6 : 0
height: _hasGimbal ? (gimbalCol.height + (ScreenTools.defaultFontPixelHeight * 2)) : 0
visible: _hasGimbal
color: Qt.rgba(qgcPal.window.r, qgcPal.window.g, qgcPal.window.b, 0.75)
radius: ScreenTools.defaultFontPixelWidth * 0.5
anchors.verticalCenter: cameraRect.verticalCenter
Column {
id: gimbalCol
spacing: ScreenTools.defaultFontPixelHeight * 0.75
anchors.centerIn: parent
QGCColoredImage {
id: gimbalIcon
source: "/custom/img/gimbal_icon.svg"
color: qgcPal.text
width: ScreenTools.defaultFontPixelWidth * 2
height: width
smooth: true
mipmap: true
antialiasing: true
fillMode: Image.PreserveAspectFit
sourceSize.width: width
anchors.horizontalCenter: parent.horizontalCenter
}
Image {
id: pitchScale
height: cameraRect.height * 0.65
source: qgcPal.globalTheme === QGCPalette.Light ? "/custom/img/gimbal_pitch_indoors.svg" : "/custom/img/gimbal_pitch_outdoors.svg"
fillMode: Image.PreserveAspectFit
sourceSize.height: height
smooth: true
mipmap: true
antialiasing: true
Image {
id: yawIndicator
width: ScreenTools.defaultFontPixelWidth * 4
source: "/custom/img/gimbal_position.svg"
fillMode: Image.PreserveAspectFit
sourceSize.width: width
x: pitchScale.width/2
y: (pitchScale.height * pitchScale.scaleRatio) + (pitchScale._pitch / pitchScale.rangeValue) * pitchScale.height
smooth: true
mipmap: true
transform: [
Translate {
x: -yawIndicator.width / 2
y: -yawIndicator.height / 2
},
Rotation {
angle: _gimbalYaw
}
]
}
readonly property real minValue: -15
readonly property real centerValue: 0
readonly property real maxValue: 90
readonly property real rangeValue: maxValue - minValue
readonly property real scaleRatio: 1/7
property real _pitch: _gimbalPitch < minValue ? minValue : (_gimbalPitch > maxValue ? maxValue : _gimbalPitch)
}
QGCLabel {
id: gimbalLabel
width: gimbalCol.width
color: qgcPal.text
font.pointSize: ScreenTools.smallFontPointSize
text: activeVehicle ? activeVehicle.gimbalPitch.toFixed(0) : "-"
horizontalAlignment: Text.AlignHCenter
}
}
} // Gimbal Indicator
}
//-- Zoom Buttons
ZoomControl {
id: zoomControl
visible: _hasZoom
mainColor: qgcPal.window
contentColor: qgcPal.text
fontPointSize: ScreenTools.defaultFontPointSize * 1.75
zoomLevelVisible: false
zoomLevel: _hasZoom ? _camera.zoomLevel : NaN
anchors.horizontalCenter: parent.horizontalCenter
onlyContinousZoom: true
onZoomIn: {
_camera.stepZoom(1)
}
onZoomOut: {
_camera.stepZoom(-1)
}
onContinuousZoomStart: {
_camera.startZoom(zoomIn ? 1 : -1)
}
onContinuousZoomStop: {
_camera.stopZoom()
}
}
}
//-------------------------------------------------------------------------
//-- Camera Settings
Popup {
id: cameraSettings
width: Math.min(mainWindow.width * 0.666, ScreenTools.defaultFontPixelWidth * 80)
height: mainWindow.height * 0.666
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)
border.color: qgcPal.text
radius: ScreenTools.defaultFontPixelWidth
}
Item {
anchors.fill: parent
anchors.margins: ScreenTools.defaultFontPixelHeight
function showEditFact(fact) {
factEditor.text = fact.valueString
factEdit.fact = fact
factEdit.visible = true
}
function hideEditFact() {
factEdit.visible = false
factEdit.fact = null
}
QGCLabel {
id: cameraSettingsLabel
text: _noSdCard ? qsTr("Settings") : (_cameraVideoMode ? qsTr("Video Settings") : qsTr("Photo Settings"))
font.family: ScreenTools.demiboldFontFamily
font.pointSize: ScreenTools.mediumFontPointSize
anchors.margins: ScreenTools.defaultFontPixelWidth
anchors.top: parent.top
anchors.left: parent.left
}
QGCFlickable {
clip: true
anchors.top: cameraSettingsLabel.bottom
anchors.bottom: parent.bottom
anchors.margins: ScreenTools.defaultFontPixelWidth
width: cameraSettingsCol.width + (ScreenTools.defaultFontPixelWidth * 2)
contentHeight: cameraSettingsCol.height
contentWidth: cameraSettingsCol.width
anchors.horizontalCenter: parent.horizontalCenter
Column {
id: cameraSettingsCol
spacing: _spacers
anchors.margins: ScreenTools.defaultFontPixelHeight
anchors.horizontalCenter: parent.horizontalCenter
//-------------------------------------------
//-- Camera Selector
Row {
spacing: ScreenTools.defaultFontPixelWidth
visible: _isCamera && _dynamicCameras.cameraLabels.length > 1
anchors.horizontalCenter: parent.horizontalCenter
QGCLabel {
text: qsTr("Camera Selector:")
width: _labelFieldWidth
anchors.verticalCenter: parent.verticalCenter
}
QGCComboBox {
model: _isCamera ? _dynamicCameras.cameraLabels : []
width: _editFieldWidth
height: _editFieldHeight
onActivated: _dynamicCameras.currentCamera = index
currentIndex: _dynamicCameras ? _dynamicCameras.currentCamera : 0
}
}
Rectangle {
color: qgcPal.button
height: 1
width: cameraSettingsCol.width
visible: _isCamera && _dynamicCameras.cameraLabels.length > 1
}
//-------------------------------------------
//-- Stream Selector
Row {
spacing: ScreenTools.defaultFontPixelWidth
visible: _isCamera && _camera.streamLabels.length > 1
anchors.horizontalCenter: parent.horizontalCenter
QGCLabel {
text: qsTr("Stream Selector:")
width: _labelFieldWidth
anchors.verticalCenter: parent.verticalCenter
}
QGCComboBox {
model: _camera ? _camera.streamLabels : []
width: _editFieldWidth
height: _editFieldHeight
onActivated: _camera.currentStream = index
currentIndex: _camera ? _camera.currentStream : 0
}
}
Rectangle {
color: qgcPal.button
height: 1
width: cameraSettingsCol.width
visible: _isCamera && _camera.streamLabels.length > 1
}
//-------------------------------------------
//-- Thermal Modes
Row {
spacing: ScreenTools.defaultFontPixelWidth
anchors.horizontalCenter: parent.horizontalCenter
visible: QGroundControl.videoManager.hasThermal
property var thermalModes: [qsTr("Off"), qsTr("Blend"), qsTr("Full"), qsTr("Picture In Picture")]
QGCLabel {
text: qsTr("Thermal View Mode")
width: _labelFieldWidth
anchors.verticalCenter: parent.verticalCenter
}
QGCComboBox {
width: _editFieldWidth
height: _editFieldHeight
model: parent.thermalModes
currentIndex: _camera ? _camera.thermalMode : 0
onActivated: _camera.thermalMode = index
}
}
Rectangle {
color: qgcPal.button
height: 1
width: cameraSettingsCol.width
visible: QGroundControl.videoManager.hasThermal
}
//-------------------------------------------
//-- Thermal Video Opacity
Row {
spacing: ScreenTools.defaultFontPixelWidth
anchors.horizontalCenter: parent.horizontalCenter
visible: QGroundControl.videoManager.hasThermal && _camera.thermalMode === QGCCameraControl.THERMAL_BLEND
QGCLabel {
text: qsTr("Blend Opacity")
width: _labelFieldWidth
anchors.verticalCenter: parent.verticalCenter
}
Slider {
width: _editFieldWidth
height: _editFieldHeight
to: 100
from: 0
value: _camera ? _camera.thermalOpacity : 0
live: true
onValueChanged: {
_camera.thermalOpacity = value
}
}
}
Rectangle {
color: qgcPal.button
height: 1
width: cameraSettingsCol.width
visible: QGroundControl.videoManager.hasThermal && _camera.thermalMode === QGCCameraControl.THERMAL_BLEND
}
//-------------------------------------------
//-- Settings from Camera Definition File
Repeater {
model: _camera ? _camera.activeSettings : []
Item {
width: repCol.width
height: repCol.height
Column {
id: repCol
spacing: _spacers
property var _fact: _camera.getFact(modelData)
Row {
height: visible ? undefined : 0
spacing: ScreenTools.defaultFontPixelWidth
anchors.horizontalCenter: parent.horizontalCenter
property bool _isBool: parent._fact.typeIsBool
property bool _isCombo: !_isBool && parent._fact.enumStrings.length > 0
property bool _isSlider: parent._fact && !isNaN(parent._fact.increment)
property bool _isEdit: !_isBool && !_isSlider && parent._fact.enumStrings.length < 1
QGCLabel {
text: parent.parent._fact.shortDescription
width: _labelFieldWidth
anchors.verticalCenter: parent.verticalCenter
}
FactComboBox {
width: parent._isCombo ? _editFieldWidth : 0
height: parent._isCombo ? _editFieldHeight : 0
fact: parent.parent._fact
indexModel: false
visible: parent._isCombo
anchors.verticalCenter: parent.verticalCenter
}
QGCButton {
visible: parent._isEdit
width: parent._isEdit ? _editFieldWidth : 0
height: parent._isEdit ? _editFieldHeight : 0
text: parent.parent._fact.valueString
onClicked: {
showEditFact(parent.parent._fact)
}
}
QGCSlider {
width: parent._isSlider ? _editFieldWidth : 0
height: parent._isSlider ? _editFieldHeight : 0
maximumValue: parent.parent._fact.max
minimumValue: parent.parent._fact.min
stepSize: parent.parent._fact.increment
visible: parent._isSlider
updateValueWhileDragging: false
anchors.verticalCenter: parent.verticalCenter
Component.onCompleted: {
value = parent.parent._fact.value
}
onValueChanged: {
parent.parent._fact.value = value
}
}
CustomOnOffSwitch {
width: parent._isBool ? _editFieldWidth : 0
height: parent._isBool ? _editFieldHeight : 0
checked: parent.parent._fact ? parent.parent._fact.value : false
onClicked: parent.parent._fact.value = checked ? 1 : 0
visible: parent._isBool
anchors.verticalCenter: parent.verticalCenter
}
}
Rectangle {
color: qgcPal.button
height: 1
width: cameraSettingsCol.width
}
}
}
}
//-------------------------------------------
//-- Time Lapse
Row {
spacing: ScreenTools.defaultFontPixelWidth
anchors.horizontalCenter: parent.horizontalCenter
visible: _cameraPhotoMode && !_noSdCard
property var photoModes: [qsTr("Single"), qsTr("Time Lapse")]
QGCLabel {
text: qsTr("Photo Mode")
width: _labelFieldWidth
anchors.verticalCenter: parent.verticalCenter
}
QGCComboBox {
width: _editFieldWidth
height: _editFieldHeight
model: parent.photoModes
currentIndex: _camera ? _camera.photoMode : 0
onActivated: _camera.photoMode = index
}
}
Rectangle {
color: qgcPal.button
height: 1
width: cameraSettingsCol.width
visible: _cameraPhotoMode && !_noSdCard
}
//-------------------------------------------
//-- Time Lapse Interval
Row {
spacing: ScreenTools.defaultFontPixelWidth
anchors.horizontalCenter: parent.horizontalCenter
visible: _cameraPhotoMode && _camera.photoMode === QGCCameraControl.PHOTO_CAPTURE_TIMELAPSE && !_noSdCard
QGCLabel {
text: qsTr("Photo Interval (seconds)")
width: _labelFieldWidth
anchors.verticalCenter: parent.verticalCenter
}
QGCSlider {
width: _editFieldWidth
height: _editFieldHeight
maximumValue: 60
minimumValue: _camera ? (_camera.isE90 ? 3 : 5) : 5
stepSize: 1
value: _camera ? _camera.photoLapse : 5
updateValueWhileDragging: true
anchors.verticalCenter: parent.verticalCenter
onValueChanged: {
if(_camera) {
_camera.photoLapse = value
}
}
}
}
Rectangle {
color: qgcPal.button
height: 1
width: cameraSettingsCol.width
visible: _cameraPhotoMode && _camera.photoMode === QGCCameraControl.PHOTO_CAPTURE_TIMELAPSE && !_noSdCard
}
//-------------------------------------------
//-- Gimbal Control
Row {
spacing: ScreenTools.defaultFontPixelWidth
visible: _camera && !_camera.isThermal
anchors.horizontalCenter: parent.horizontalCenter
QGCLabel {
text: qsTr("Show Gimbal Control")
width: _labelFieldWidth
anchors.verticalCenter: parent.verticalCenter
}
CustomOnOffSwitch {
checked: CustomQuickInterface.showGimbalControl
width: _editFieldWidth
height: _editFieldHeight
anchors.verticalCenter: parent.verticalCenter
onClicked: CustomQuickInterface.showGimbalControl = checked
}
}
Rectangle {
color: qgcPal.button
height: 1
width: cameraSettingsCol.width
visible: _camera && !_camera.isThermal
}
//-------------------------------------------
//-- Screen Grid
Row {
spacing: ScreenTools.defaultFontPixelWidth
visible: _camera && !_camera.isThermal
anchors.horizontalCenter: parent.horizontalCenter
QGCLabel {
text: qsTr("Screen Grid")
width: _labelFieldWidth
anchors.verticalCenter: parent.verticalCenter
}
CustomOnOffSwitch {
checked: QGroundControl.settingsManager.videoSettings.gridLines.rawValue
width: _editFieldWidth
height: _editFieldHeight
anchors.verticalCenter: parent.verticalCenter
onClicked: QGroundControl.settingsManager.videoSettings.gridLines.rawValue = checked
}
}
Rectangle {
color: qgcPal.button
height: 1
width: cameraSettingsCol.width
visible: _camera && !_camera.isThermal
}
//-------------------------------------------
//-- Video Fit
Row {
spacing: ScreenTools.defaultFontPixelWidth
visible: _camera
anchors.horizontalCenter: parent.horizontalCenter
QGCLabel {
text: qsTr("Video Screen Fit")
width: _labelFieldWidth
anchors.verticalCenter: parent.verticalCenter
}
FactComboBox {
width: _editFieldWidth
height: _editFieldHeight
fact: QGroundControl.settingsManager.videoSettings.videoFit
indexModel: false
anchors.verticalCenter: parent.verticalCenter
}
}
Rectangle {
color: qgcPal.button
height: 1
width: cameraSettingsCol.width
visible: _camera && !_camera.isThermal
}
//-------------------------------------------
//-- Reset Camera
Row {
spacing: ScreenTools.defaultFontPixelWidth
anchors.horizontalCenter: parent.horizontalCenter
QGCLabel {
text: qsTr("Reset Camera Defaults")
width: _labelFieldWidth
anchors.verticalCenter: parent.verticalCenter
}
QGCButton {
text: qsTr("Reset")
onClicked: resetPrompt.open()
width: _editFieldWidth
height: _editFieldHeight
enabled: !_recordingVideo
anchors.verticalCenter: parent.verticalCenter
MessageDialog {
id: resetPrompt
title: qsTr("Reset Camera to Factory Settings")
text: qsTr("Confirm resetting all settings?")
standardButtons: StandardButton.Yes | StandardButton.No
onNo: resetPrompt.close()
onYes: {
_camera.resetSettings()
QGroundControl.settingsManager.videoSettings.gridLines.rawValue = false
_camera.photoMode = QGCCameraControl.PHOTO_CAPTURE_SINGLE
_camera.photoLapse = 5.0
_camera.photoLapseCount = 0
resetPrompt.close()
}
}
}
}
Rectangle {
color: qgcPal.button
height: 1
width: cameraSettingsCol.width
}
}
}
Rectangle {
id: factEdit
visible: false
color: qgcPal.globalTheme === QGCPalette.Light ? Qt.rgba(1,1,1,0.5) : Qt.rgba(0,0,0,0.5)
anchors.fill: parent
property var fact: null
DeadMouseArea {
anchors.fill: parent
}
Rectangle {
width: factEditCol.width * 1.25
height: factEditCol.height * 1.25
color: qgcPal.globalTheme === QGCPalette.Light ? Qt.rgba(1,1,1,0.95) : Qt.rgba(0,0,0,0.75)
border.width: 1
border.color: qgcPal.globalTheme === QGCPalette.Light ? Qt.rgba(0,0,0,0.35) : Qt.rgba(1,1,1,0.35)
anchors.top: parent.top
anchors.topMargin: ScreenTools.defaultFontPixelHeight * 8
anchors.horizontalCenter: parent.horizontalCenter
Column {
id: factEditCol
spacing: ScreenTools.defaultFontPixelHeight
anchors.centerIn: parent
QGCLabel {
text: factEdit.fact ? factEdit.fact.shortDescription : ""
anchors.horizontalCenter: parent.horizontalCenter
}
FactTextField {
id: factEditor
width: _editFieldWidth
fact: factEdit.fact
anchors.horizontalCenter: parent.horizontalCenter
}
QGCButton {
text: qsTr("Close")
anchors.horizontalCenter: parent.horizontalCenter
onClicked: {
factEditor.completeEditing()
hideEditFact()
}
}
}
}
}
}
}
//-------------------------------------------------------------------------
//-- Thermal Palettes
Popup {
id: thermalPalettes
width: Math.min(mainWindow.width * 0.666, ScreenTools.defaultFontPixelWidth * 40)
height: mainWindow.height * 0.5
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)
border.color: qgcPal.text
radius: ScreenTools.defaultFontPixelWidth * 0.5
}
Item {
anchors.fill: parent
anchors.margins: ScreenTools.defaultFontPixelHeight
QGCFlickable {
clip: true
anchors.fill: parent
width: comboListCol.width + (ScreenTools.defaultFontPixelWidth * 2)
contentHeight: comboListCol.height
contentWidth: comboListCol.width
anchors.horizontalCenter: parent.horizontalCenter
ColumnLayout {
id: comboListCol
spacing: ScreenTools.defaultFontPixelHeight
anchors.margins: ScreenTools.defaultFontPixelHeight
anchors.horizontalCenter: parent.horizontalCenter
QGCLabel {
text: qsTr("Thermal Palettes")
Layout.alignment: Qt.AlignHCenter
}
Repeater {
model: _irPaletteFact ? _irPaletteFact.enumStrings : []
QGCButton {
text: modelData
Layout.minimumHeight: ScreenTools.defaultFontPixelHeight * 3
Layout.minimumWidth: ScreenTools.defaultFontPixelWidth * 30
Layout.fillHeight: true
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter
checked: index === _irPaletteFact.value
onClicked: {
_irPaletteFact.value = index
if(thermalBackgroundRect.visible) {
if(_camera.thermalMode !== QGCCameraControl.THERMAL_PIP && _camera.thermalMode !== QGCCameraControl.THERMAL_FULL) {
_camera.thermalMode = QGCCameraControl.THERMAL_FULL
thermalFull.checked = true
}
}
thermalPalettes.close()
}
}
}
}
}
}
}
}
......@@ -16,18 +16,14 @@ import QtQuick.Dialogs 1.3
import QtPositioning 5.2
import QGroundControl 1.0
import QGroundControl.Controllers 1.0
import QGroundControl.Controls 1.0
import QGroundControl.FlightMap 1.0
import QGroundControl.MultiVehicleManager 1.0
import QGroundControl.Palette 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.Vehicle 1.0
import QGroundControl.QGCPositionManager 1.0
import QGroundControl.Airspace 1.0
import CustomQuickInterface 1.0
import Custom.Widgets 1.0
import Custom.Widgets 1.0
Item {
anchors.fill: parent
......@@ -42,17 +38,7 @@ Item {
property var _sepColor: qgcPal.globalTheme === QGCPalette.Light ? Qt.rgba(0,0,0,0.5) : Qt.rgba(1,1,1,0.5)
property color _indicatorsColor: qgcPal.text
property bool _communicationLost: activeVehicle ? activeVehicle.connectionLost : false
property bool _isVehicleGps: activeVehicle && activeVehicle.gps && activeVehicle.gps.count.rawValue > 1 && activeVehicle.gps.hdop.rawValue < 1.4
property var _dynamicCameras: activeVehicle ? activeVehicle.dynamicCameras : null
property bool _isCamera: _dynamicCameras ? _dynamicCameras.cameras.count > 0 : false
property int _curCameraIndex: _dynamicCameras ? _dynamicCameras.currentCamera : 0
property var _camera: _isCamera ? _dynamicCameras.cameras.get(_curCameraIndex) : null
property bool _cameraPresent: _camera && _camera.cameraMode !== QGCCameraControl.CAM_MODE_UNDEFINED
property var _flightPermit: QGroundControl.airmapSupported ? QGroundControl.airspaceManager.flightPlan.flightPermitStatus : null
property bool _hasGimbal: activeVehicle && activeVehicle.gimbalData
property bool _airspaceIndicatorVisible: QGroundControl.airmapSupported && mainIsMap && _flightPermit && _flightPermit !== AirspaceFlightPlanProvider.PermitNone
property string _altitude: activeVehicle ? (isNaN(activeVehicle.altitudeRelative.value) ? "0.0" : activeVehicle.altitudeRelative.value.toFixed(1)) + ' ' + activeVehicle.altitudeRelative.units : "0.0"
property string _distanceStr: isNaN(_distance) ? "0" : _distance.toFixed(0) + ' ' + (activeVehicle ? activeVehicle.altitudeRelative.units : "")
......@@ -73,31 +59,7 @@ Item {
return hours+':'+minutes+':'+seconds;
}
Timer {
id: connectionTimer
interval: 5000
running: false;
repeat: false;
onTriggered: {
//-- Vehicle is gone
if(activeVehicle) {
//-- Let video stream close
QGroundControl.settingsManager.videoSettings.rtspTimeout.rawValue = 1
if(!activeVehicle.armed) {
//-- If it wasn't already set to auto-disconnect
if(!activeVehicle.autoDisconnect) {
//-- Vehicle is not armed. Close connection and tell user.
activeVehicle.disconnectInactiveVehicle()
connectionLostDisarmedDialog.open()
}
} else {
//-- Vehicle is armed. Show doom dialog.
connectionLostArmed.open()
}
}
}
}
// FIXE: Isn't distance to home in factgroup
Connections {
target: QGroundControl.qgcPositionManger
onGcsPositionChanged: {
......@@ -116,43 +78,6 @@ Item {
}
}
Connections {
target: QGroundControl.multiVehicleManager.activeVehicle
onConnectionLostChanged: {
if(!_communicationLost) {
//-- Communication regained
connectionTimer.stop();
if(connectionLostArmed.visible) {
connectionLostArmed.close()
}
//-- Reset stream timeout
QGroundControl.settingsManager.videoSettings.rtspTimeout.rawValue = 60
} else {
if(activeVehicle && !activeVehicle.autoDisconnect) {
//-- Communication lost
connectionTimer.start();
}
}
}
}
Connections {
target: QGroundControl.multiVehicleManager
onVehicleAdded: {
//-- Dismiss comm lost dialog if open
connectionLostDisarmedDialog.close()
}
}
//-------------------------------------------------------------------------
MessageDialog {
id: connectionLostDisarmedDialog
title: qsTr("Communication Lost")
text: qsTr("Connection to vehicle has been lost and closed.")
standardButtons: StandardButton.Ok
onAccepted: {
connectionLostDisarmedDialog.close()
}
}
//-------------------------------------------------------------------------
//-- Heading Indicator
Rectangle {
......@@ -163,7 +88,7 @@ Item {
radius: 2
clip: true
anchors.top: parent.top
anchors.topMargin: ScreenTools.defaultFontPixelHeight * (_airspaceIndicatorVisible ? 3 : 1)
anchors.topMargin: ScreenTools.defaultFontPixelHeight
anchors.horizontalCenter: parent.horizontalCenter
visible: !mainIsMap
Repeater {
......@@ -182,7 +107,7 @@ Item {
visible: _angle % 45 == 0
color: "#75505565"
font.pointSize: ScreenTools.smallFontPointSize
text: {
text: {
switch(_angle) {
case 0: return "N"
case 45: return "NE"
......@@ -226,28 +151,6 @@ Item {
anchors.horizontalCenter: parent.horizontalCenter
}
//-------------------------------------------------------------------------
//-- Camera Control
Loader {
id: camControlLoader
visible: !mainIsMap && _cameraPresent && _camera.paramComplete
source: visible ? "/custom/CustomCameraControl.qml" : ""
anchors.right: parent.right
anchors.rightMargin: ScreenTools.defaultFontPixelWidth
anchors.top: parent.top
anchors.topMargin: ScreenTools.defaultFontPixelHeight
}
//-------------------------------------------------------------------------
//-- Map Scale
MapScale {
id: mapScale
anchors.left: parent.left
anchors.top: parent.top
anchors.topMargin: ScreenTools.defaultFontPixelHeight * 0.5
anchors.leftMargin: ScreenTools.defaultFontPixelWidth * 16
mapControl: mainWindow.flightDisplayMap
visible: rootBackground.visible && mainIsMap
}
//-------------------------------------------------------------------------
//-- Vehicle Indicator
Rectangle {
id: vehicleIndicator
......@@ -260,9 +163,6 @@ Item {
anchors.right: attitudeIndicator.visible ? attitudeIndicator.left : parent.right
anchors.rightMargin: attitudeIndicator.visible ? -ScreenTools.defaultFontPixelWidth : ScreenTools.defaultFontPixelWidth
readonly property bool _showGps: CustomQuickInterface.showAttitudeWidget
GridLayout {
id: vehicleStatusGrid
columnSpacing: ScreenTools.defaultFontPixelWidth * 1.5
......@@ -270,62 +170,6 @@ Item {
columns: 7
anchors.centerIn: parent
//-- Latitude
QGCLabel {
height: _indicatorsHeight
width: height
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
color: qgcPal.text
text: "Lat:"
visible: vehicleIndicator._showGps
}
QGCLabel {
id: firstLabel
text: activeVehicle ? activeVehicle.gps.lat.value.toFixed(activeVehicle.gps.lat.decimalPlaces) : "-"
color: _indicatorsColor
font.pointSize: ScreenTools.smallFontPointSize
Layout.fillWidth: true
Layout.minimumWidth: indicatorValueWidth
horizontalAlignment: Text.AlignLeft
visible: vehicleIndicator._showGps
}
//-- Longitude
QGCLabel {
height: _indicatorsHeight
width: height
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
color: qgcPal.text
text: "Lon:"
visible: vehicleIndicator._showGps
}
QGCLabel {
text: activeVehicle ? activeVehicle.gps.lon.value.toFixed(activeVehicle.gps.lon.decimalPlaces) : "-"
color: _indicatorsColor
font.pointSize: ScreenTools.smallFontPointSize
Layout.fillWidth: true
Layout.minimumWidth: indicatorValueWidth
horizontalAlignment: firstLabel.horizontalAlignment
visible: vehicleIndicator._showGps
}
//-- HDOP
QGCLabel {
height: _indicatorsHeight
width: height
Layout.alignment: Qt.AlignVCenter | Qt.AlignHCenter
color: qgcPal.text
text: "HDOP:"
visible: vehicleIndicator._showGps
}
QGCLabel {
text: activeVehicle ? activeVehicle.gps.hdop.value.toFixed(activeVehicle.gps.hdop.decimalPlaces) : "-"
color: _indicatorsColor
font.pointSize: ScreenTools.smallFontPointSize
Layout.fillWidth: true
Layout.minimumWidth: indicatorValueWidth
horizontalAlignment: firstLabel.horizontalAlignment
visible: vehicleIndicator._showGps
}
//-- Compass
Item {
Layout.rowSpan: 3
......@@ -408,16 +252,17 @@ Item {
color: qgcPal.text
}
QGCLabel {
id: firstLabel
text: {
if(activeVehicle)
return secondsToHHMMSS(activeVehicle.getFact("flightTime").value)
if(activeVehicle)
return secondsToHHMMSS(activeVehicle.getFact("flightTime").value)
return "00:00:00"
}
color: _indicatorsColor
font.pointSize: ScreenTools.smallFontPointSize
Layout.fillWidth: true
Layout.minimumWidth: indicatorValueWidth
horizontalAlignment: firstLabel.horizontalAlignment
horizontalAlignment: Text.AlignLeft
}
//-- Ground Speed
QGCColoredImage {
......@@ -515,10 +360,6 @@ Item {
horizontalAlignment: firstLabel.horizontalAlignment
}
}
MouseArea {
anchors.fill: parent
onDoubleClicked: CustomQuickInterface.showAttitudeWidget = !CustomQuickInterface.showAttitudeWidget
}
}
//-------------------------------------------------------------------------
//-- Attitude Indicator
......@@ -526,7 +367,6 @@ Item {
color: qgcPal.window
width: attitudeIndicator.width * 0.5
height: vehicleIndicator.height
visible: CustomQuickInterface.showAttitudeWidget
anchors.top: vehicleIndicator.top
anchors.left: vehicleIndicator.right
}
......@@ -540,197 +380,11 @@ Item {
width: height
radius: height * 0.5
color: qgcPal.windowShade
visible: CustomQuickInterface.showAttitudeWidget
CustomAttitudeWidget {
CustomAttitudeWidget {
size: parent.height * 0.95
vehicle: activeVehicle
showHeading: false
anchors.centerIn: parent
}
}
//-------------------------------------------------------------------------
//-- Multi Vehicle Selector
Row {
id: multiVehicleSelector
spacing: ScreenTools.defaultFontPixelWidth
anchors.bottom: parent.bottom
anchors.bottomMargin: ScreenTools.defaultFontPixelWidth * 1.5
anchors.right: vehicleIndicator.left
anchors.rightMargin: ScreenTools.defaultFontPixelWidth
visible: QGroundControl.multiVehicleManager.vehicles.count > 1
Repeater {
model: QGroundControl.multiVehicleManager.vehicles.count
CustomVehicleButton {
property var _vehicle: QGroundControl.multiVehicleManager.vehicles.get(modelData)
vehicle: _vehicle
checked: (_vehicle && activeVehicle) ? _vehicle.id === activeVehicle.id : false
onClicked: {
QGroundControl.multiVehicleManager.activeVehicle = _vehicle
}
}
}
}
//-------------------------------------------------------------------------
//-- Gimbal Control
Rectangle {
id: gimbalControl
visible: camControlLoader.visible && CustomQuickInterface.showGimbalControl && _hasGimbal
anchors.bottom: camControlLoader.bottom
anchors.right: camControlLoader.left
anchors.rightMargin: ScreenTools.defaultFontPixelWidth * (QGroundControl.videoManager.hasThermal ? -1 : 1)
height: parent.width * 0.125
width: height
color: Qt.rgba(1,1,1,0.25)
radius: width * 0.5
property real _currentPitch: 0
property real _currentYaw: 0
property real time_last_seconds:0
property real _lastHackedYaw: 0
property real speedMultiplier: 5
property real maxRate: 20
property real exponentialFactor:0.6
property real kPFactor: 3
property real reportedYawDeg: activeVehicle ? activeVehicle.gimbalYaw : NaN
property real reportedPitchDeg: activeVehicle ? activeVehicle.gimbalPitch : NaN
Timer {
interval: 100 //-- 10Hz
running: gimbalControl.visible && activeVehicle
repeat: true
onTriggered: {
if (activeVehicle) {
var yaw = gimbalControl._currentYaw
var oldYaw = yaw;
var pitch = gimbalControl._currentPitch
var oldPitch = pitch;
var pitch_stick = (stick.yAxis * 2.0 - 1.0)
if(_camera && _camera.vendor === "NextVision") {
var time_current_seconds = ((new Date()).getTime())/1000.0
if(gimbalControl.time_last_seconds === 0.0)
gimbalControl.time_last_seconds = time_current_seconds
var pitch_angle = gimbalControl._currentPitch
// Preparing stick input with exponential curve and maximum rate
var pitch_expo = (1 - gimbalControl.exponentialFactor) * pitch_stick + gimbalControl.exponentialFactor * pitch_stick * pitch_stick * pitch_stick
var pitch_rate = pitch_stick * gimbalControl.maxRate
var pitch_angle_reported = gimbalControl.reportedPitchDeg
// Integrate the angular rate to an angle time abstracted
pitch_angle += pitch_rate * (time_current_seconds - gimbalControl.time_last_seconds)
// Control the angle quicker by driving the gimbal internal angle controller into saturation
var pitch_angle_error = pitch_angle - pitch_angle_reported
pitch_angle_error = Math.round(pitch_angle_error)
var pitch_setpoint = pitch_angle + pitch_angle_error * gimbalControl.kPFactor
//console.info("error: " + pitch_angle_error + "; angle_state: " + pitch_angle)
pitch = pitch_setpoint
yaw += stick.xAxis * gimbalControl.speedMultiplier
yaw = clamp(yaw, -180, 180)
pitch = clamp(pitch, -90, 45)
pitch_angle = clamp(pitch_angle, -90, 45)
//console.info("P: " + pitch + "; Y: " + yaw)
activeVehicle.gimbalControlValue(pitch, yaw);
gimbalControl._currentYaw = yaw
gimbalControl._currentPitch = pitch_angle
gimbalControl.time_last_seconds = time_current_seconds
} else {
yaw += stick.xAxis * gimbalControl.speedMultiplier
var hackedYaw = yaw + (stick.xAxis * gimbalControl.speedMultiplier * 50)
pitch += pitch_stick * gimbalControl.speedMultiplier
hackedYaw = clamp(hackedYaw, -180, 180)
yaw = clamp(yaw, -180, 180)
pitch = clamp(pitch, -90, 90)
if(gimbalControl._lastHackedYaw !== hackedYaw || gimbalControl.hackedYaw !== oldYaw || pitch !== oldPitch) {
activeVehicle.gimbalControlValue(pitch, hackedYaw)
gimbalControl._lastHackedYaw = hackedYaw
gimbalControl._currentPitch = pitch
gimbalControl._currentYaw = yaw
}
}
}
}
function clamp(num, min, max) {
return Math.min(Math.max(num, min), max);
}
}
JoystickThumbPad {
id: stick
anchors.fill: parent
lightColors: qgcPal.globalTheme === QGCPalette.Light
yAxisThrottle: true
yAxisThrottleCentered: true
xAxis: 0
yAxis: 0.5
}
}
//-------------------------------------------------------------------------
//-- Object Avoidance
Item {
visible: activeVehicle && activeVehicle.objectAvoidance.available && activeVehicle.objectAvoidance.enabled
anchors.centerIn: parent
width: parent.width * 0.5
height: parent.height * 0.5
Repeater {
model: activeVehicle && activeVehicle.objectAvoidance.gridSize > 0 ? activeVehicle.objectAvoidance.gridSize : []
Rectangle {
width: ScreenTools.defaultFontPixelWidth
height: width
radius: width * 0.5
color: distance < 0.25 ? "red" : "orange"
x: (parent.width * activeVehicle.objectAvoidance.grid(modelData).x) + (parent.width * 0.5)
y: (parent.height * activeVehicle.objectAvoidance.grid(modelData).y) + (parent.height * 0.5)
property real distance: activeVehicle.objectAvoidance.distance(modelData)
}
}
}
//-------------------------------------------------------------------------
//-- Connection Lost While Armed
Popup {
id: connectionLostArmed
width: mainWindow.width * 0.666
height: connectionLostArmedCol.height * 1.5
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.alertBackground
border.color: qgcPal.alertBorder
radius: ScreenTools.defaultFontPixelWidth
}
Column {
id: connectionLostArmedCol
spacing: ScreenTools.defaultFontPixelHeight * 3
anchors.margins: ScreenTools.defaultFontPixelHeight
showHeading: false
anchors.centerIn: parent
QGCLabel {
text: qsTr("Communication Lost")
font.family: ScreenTools.demiboldFontFamily
font.pointSize: ScreenTools.largeFontPointSize
color: qgcPal.alertText
anchors.horizontalCenter: parent.horizontalCenter
}
QGCLabel {
text: qsTr("Warning: Connection to vehicle lost.")
color: qgcPal.alertText
font.family: ScreenTools.demiboldFontFamily
font.pointSize: ScreenTools.mediumFontPointSize
anchors.horizontalCenter: parent.horizontalCenter
}
QGCLabel {
text: qsTr("The vehicle will automatically cancel the flight and return to land. Ensure a clear line of sight between transmitter and vehicle. Ensure the takeoff location is clear.")
width: connectionLostArmed.width * 0.75
wrapMode: Text.WordWrap
color: qgcPal.alertText
font.family: ScreenTools.demiboldFontFamily
font.pointSize: ScreenTools.mediumFontPointSize
anchors.horizontalCenter: parent.horizontalCenter
}
}
}
}
<?xml version="1.0" encoding="utf-8"?>
<!-- Svg Vector Icons : http://www.onlinewebfonts.com/icon -->
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd">
<svg version="1.1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 1000 1000" enable-background="new 0 0 1000 1000" xml:space="preserve">
<metadata> Svg Vector Icons : http://www.onlinewebfonts.com/icon </metadata>
<g><g transform="translate(0.000000,511.000000) scale(0.100000,-0.100000)"><path d="M1411.9,2317.3c-26.8-28.7-32.6-92-36.4-365.9l-5.7-333.3l-84.3-24.9c-203.1-59.4-264.4-205-210.7-496.1c90-488.5,454-672.4,687.7-350.5c82.4,113,153.2,350.5,153.2,515.3V1394h773.9h772l47.9-109.2l47.9-109.2l-113-82.4c-295-216.5-521-542.1-630.2-906.1c-42.1-137.9-44.1-174.3-51.7-1021c-5.8-927.1-5.8-932.9,80.4-932.9c78.5,0,88.1,32.6,88.1,291.2v245.2h95.8h95.8v220.3v220.3h-97.7h-99.6l11.5,379.3c11.5,419.5,32.6,536.4,137.9,764.3C3183.8,591.3,3360,809.7,3565,961l70.9,51.7l34.5-72.8c21.1-40.2,57.5-82.4,84.3-95.8c69-34.5,2421.3-34.5,2490.2,0c26.8,13.4,63.2,55.6,84.3,95.8l34.5,72.8l70.9-51.7c203-151.3,381.2-369.7,488.5-605.3c109.2-237.5,128.3-348.6,139.8-766.2l11.5-379.3h-99.6H6877v-220.3v-220.3h95.8h95.8v-245.2c0-258.6,9.6-291.2,88.1-291.2c86.2,0,86.2,5.7,80.5,932.9c-7.6,846.7-9.6,883.1-51.7,1021c-111.1,367.8-335.2,687.7-636,909.9l-109.2,80.4l47.9,109.2l49.8,107.3H7308h772l7.7-166.7c23-415.7,243.3-699.2,494.2-632.1c84.3,23,149.4,72.8,214.5,168.6c116.8,174.3,185.8,542.1,124.5,662.8c-44.1,86.2-139.8,157.1-226,170.5l-74.7,13.4v339.1c0,304.6-3.8,342.9-34.5,369.7c-42.1,38.3-99.6,42.1-147.5,7.7c-30.6-24.9-34.5-57.5-32.6-364l1.9-339.1l-1093.8,3.8l-1095.7,5.7l-17.2,67c-30.7,116.9-21.1,114.9-461.7,114.9h-404.2l-46,67.1c-55.6,82.4-180.1,143.7-289.2,143.7c-109.2,0-241.4-65.1-293.1-145.6l-42.1-65.1h-404.2c-440.6,0-431,1.9-461.7-114.9l-17.2-67l-1095.7-5.7l-1095.7-3.8v344.8c0,319.9-1.9,344.8-36.4,364C1498.1,2361.3,1446.3,2355.6,1411.9,2317.3z"/><path d="M297,2102.7c-182-38.3-233.7-86.2-172.4-153.2c101.5-111.1,457.8-168.6,837.1-136c139.8,13.4,262.4,30.7,270.1,38.3c9.6,9.6,13.4,53.6,9.6,99.6c-5.7,80.4-7.7,84.3-72.8,90c-36.4,3.8-136,19.2-220.3,34.5C758.7,2110.4,400.4,2125.7,297,2102.7z"/><path d="M1925.2,2102.7c-82.4-9.6-162.8-23-176.2-26.8c-26.8-11.5-36.4-183.9-9.6-183.9c7.7,0,116.9-17.2,243.3-36.4c329.5-53.6,500-65.1,645.6-42.1c319.9,46,325.6,166.7,15.3,260.5C2517.1,2112.3,2143.6,2127.6,1925.2,2102.7z"/><path d="M7432.5,2093.1c-180.1-40.2-296.9-105.4-296.9-162.8c0-59.4,65.1-91.9,235.6-116.9c145.6-23,316.1-11.5,645.5,42.1c126.4,19.2,237.5,36.4,245.2,36.4c7.7,0,13.4,40.2,9.6,90c-5.7,90-7.6,91.9-82.4,105.4C8012.9,2118,7558.9,2121.9,7432.5,2093.1z"/><path d="M9281,2110.4c-30.6-3.8-134.1-21.1-229.9-36.4c-93.9-15.3-197.3-30.6-229.9-32.6c-55.6-5.7-57.5-9.6-63.2-105.4c-3.8-74.7,1.9-101.5,19.2-101.5c13.4,0,134.1-9.6,268.2-21.1c275.8-24.9,521-3.8,693.4,59.4c283.5,107.3,180.1,226-208.8,239.4C9424.7,2116.1,9313.6,2114.2,9281,2110.4z"/><path d="M4584,263.8c-34.5-19.2-74.7-61.3-90-91.9l-28.7-55.6l-386.9-1.9c-214.5-1.9-417.6-13.4-450.2-23c-82.4-26.8-191.6-151.3-216.5-243.3c-28.7-103.4-28.7-1626.3,0-1712.5c34.5-101.5,111.1-189.6,197.3-229.9c74.7-34.5,149.4-36.4,1390.7-36.4c1241.3,0,1316,1.9,1390.7,36.4c93.9,42.1,168.6,134.1,197.3,241.4c28.7,101.5,28.7,1599.5,0,1701c-24.9,90-120.7,203.1-205,237.5c-46,19.2-160.9,26.8-421.4,26.8c-197.3,0-377.4,3.8-398.4,9.6c-23,5.8-49.8,30.7-63.2,57.5c-11.5,24.9-47.9,63.2-82.4,84.3c-57.5,34.5-97.7,38.3-417.6,38.3C4681.7,302.1,4639.6,298.3,4584,263.8z M6246.7-232.4c65.1-67,70.9-130.3,15.3-201.1c-80.5-101.5-266.3-40.2-266.3,88.1C5995.8-190.2,6139.5-127,6246.7-232.4z M5329.2-280.2c327.5-157.1,519.1-515.3,457.8-852.4c-72.8-396.5-394.6-672.4-787.3-672.4c-390.8,0-724.1,283.5-791.1,676.2c-61.3,365.9,164.7,743.3,528.7,877.3C4890.5-194,5181.7-207.5,5329.2-280.2z"/><path d="M4831.2-538.8c-126.4-44.1-237.5-147.5-293.1-277.8c-76.6-180.1-24.9-425.3,120.7-561.3c170.5-159,461.6-164.7,660.9-13.4c160.9,122.6,224.1,383.1,139.8,578.5c-55.5,128.3-183.9,243.3-312.2,281.6C5022.7-494.8,4955.7-494.8,4831.2-538.8z"/></g></g>
</svg>
\ No newline at end of file
<?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>
<?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>
<?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>
<?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>
<?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:#69BD48;}
.st1{fill:#231F20;}
</style>
<rect x="44.998" y="94.501" class="st0" width="128.109" height="136.125"/>
<path class="st1" d="M251.546,247.045H4.502c-1.346,0-2.251,0.452-3.156,1.345C0.453,249.296,0,250.652,0,251.999
c1.346,20.244,18.446,35.999,38.702,35.999h178.652c20.244,0,37.344-15.755,38.702-35.999c0-1.346-0.452-2.704-1.345-3.596
c-0.917-0.906-1.81-1.358-3.168-1.358H251.546z M137.7,272.255h-19.803c-2.703,0-4.501-2.251-4.501-4.502
c0-2.25,1.798-4.501,4.501-4.501H137.7c2.251,0,4.502,2.251,4.502,4.501C142.202,270.004,140.404,272.255,137.7,272.255z"/>
<path class="st1" d="M274.495,0.002h-74.689c-7.645,0-13.504,6.3-13.504,13.504v106.201L288,119.696V13.507
c0-7.205-6.299-13.504-13.504-13.504L274.495,0.002z"/>
<path class="st1" d="M186.296,147.156c0,7.645,5.847,13.504,13.505,13.504l74.689-0.011c7.645,0,13.504-6.3,13.504-13.505v-18.446
H186.296V147.156z M230.395,139.952h13.505c2.703,0,4.501,1.798,4.501,4.501c0,2.704-1.798,4.502-4.501,4.502h-13.505
c-2.703,0-4.501-1.798-4.501-4.502C225.894,141.75,227.703,139.952,230.395,139.952z"/>
<path class="st1" d="M18.899,238.054h218.247c2.704,0,4.502-2.251,4.502-4.502V169.65h-41.847c-12.6,0-22.495-10.349-22.495-22.495
V77.408L27.448,77.396c-7.205,0-13.052,5.847-13.052,13.052v143.106c0,2.704,1.798,4.502,4.501,4.502L18.899,238.054z
M102.606,135.45l26.997-12.146l-8.551-3.156c-2.25-0.905-3.596-3.597-2.703-5.848c0.905-2.251,3.596-3.596,5.847-2.703
l18.446,6.752c0.906,0.452,2.251,1.346,2.704,2.251c0.452,0.905,0.452,2.251,0,3.596l-6.752,18.446
c-0.906,2.251-3.597,3.596-5.848,2.704c-2.25-0.906-3.596-3.596-2.703-5.847l3.156-8.551l-26.997,12.147
c-2.251,0.905-4.954,0-5.847-2.251C98.997,139.046,100.355,136.354,102.606,135.45L102.606,135.45z M81.004,190.802l6.752-18.446
c0.905-2.251,3.596-3.596,5.847-2.704c2.251,0.906,3.596,3.597,2.703,5.847l-3.156,8.551l26.996-12.147
c2.251-0.905,4.954,0,5.847,2.251c0.906,2.251,0,4.954-2.25,5.847l-26.997,12.147l8.55,3.156c2.251,0.905,3.596,3.596,2.703,5.847
c-0.905,2.251-3.596,3.596-5.847,2.703l-18.446-6.752c-0.905-0.453-2.251-1.345-2.703-2.251
C81.445,193.946,80.551,193.053,81.004,190.802L81.004,190.802z"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.4, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
<svg version="1.1"
id="Layer_1" xmlns:cc="http://creativecommons.org/ns#" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd" xmlns:svg="http://www.w3.org/2000/svg"
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">
<g transform="translate(0,-952.36218)">
<path d="M102.3,978.9c-3.2,0.1-5.5,2.1-6.7,4.1l-13.1,26.2H30.3c-16.7,0-30.3,13.7-30.3,30.3v144c0,16.7,13.7,30.3,30.3,30.3h227.4
c16.7,0,30.3-13.7,30.3-30.3v-144c0-16.7-13.7-30.3-30.3-30.3h-52.1L192.4,983c-1.3-2.5-4-4.1-6.7-4.1H102.3z M106.9,994h74.1
l13,26.1c1.2,2.5,3.9,4.2,6.7,4.3h56.8c8.5,0,15.2,6.6,15.2,15.2v144c0,8.5-6.6,15.2-15.2,15.2H30.3c-8.5,0-15.2-6.6-15.2-15.2
v-144c0-8.5,6.6-15.2,15.2-15.2h56.8c2.8,0,5.5-1.7,6.7-4.3L106.9,994z M144,1047.1c-35.5,0-64.4,28.9-64.4,64.4
c0,35.5,28.9,64.4,64.4,64.4c35.5,0,64.4-28.9,64.4-64.4C208.4,1076,179.5,1047.1,144,1047.1z M144,1062.3
c27.3,0,49.3,22,49.3,49.3c0,27.3-22,49.3-49.3,49.3c-27.3,0-49.3-22-49.3-49.3C94.7,1084.2,116.7,1062.3,144,1062.3z"/>
</g>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.4, 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 72 72" style="enable-background:new 0 0 72 72;" xml:space="preserve">
<style type="text/css">
.st0{fill-rule:evenodd;clip-rule:evenodd;}
</style>
<path class="st0" d="M63.6,65.5h-5.5V40h5.5V65.5z M18.6,31.2H3.4c-4.5,0-4.5-9.1,0-9.1h15.2C23.2,22.1,23.2,31.2,18.6,31.2z
M8.2,65.5h5.7V35H8.2V65.5z M8.2,18.3V6.5h5.7v11.8H8.2z M28.4,51h15.2c4.5,0,4.5-9.3,0-9.3H28.4C23.9,41.7,23.9,51,28.4,51z
M38.6,65.5h-5.5V54.6h5.5V65.5z M33.2,6.5V38h5.5V6.4L33.2,6.5L33.2,6.5z M68.4,36.2h-15c-4.8,0-4.8-9.1,0-9.1h15
C73.2,27.1,73.2,36.2,68.4,36.2z M58.2,6.5v16.8h5.4V6.5H58.2z"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.4, 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">
<g>
<path d="M21.2,215.3h168.7c11.7,0,21.2-9.5,21.2-21.2V93.9c0-11.7-9.5-21.2-21.2-21.2H21.2C9.5,72.7,0,82.2,0,93.9v100.2
C0,205.8,9.5,215.3,21.2,215.3z"/>
<polygon points="225.2,165.5 288,206.1 288,81.9 225.2,122.5 "/>
</g>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.4, 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 72 72" style="enable-background:new 0 0 72 72;" xml:space="preserve">
<style type="text/css">
.st0{fill-rule:evenodd;clip-rule:evenodd;fill:#FFFFFF;}
</style>
<title>670134</title>
<desc>Created with Sketch.</desc>
<path class="st0" d="M19.589,25.301L19.589,25.301c1.113-0.307,2.259,0.344,2.57,1.453c0.307,1.109-0.345,2.258-1.453,2.565
c-7.701,2.139-13.367,9.206-13.359,17.587c0,3.427,0.996,6.588,2.637,9.322l0.775-4.4c0.198-1.135,1.281-1.895,2.416-1.693
c1.135,0.198,1.895,1.281,1.693,2.416L13.26,61.67l-0.378,0.595c-0.09,0.157-0.067,0.352-0.202,0.487
c-0.041,0.041-0.101,0.022-0.146,0.06l-0.131,0.206l-0.79,0.176c-0.191,0.037-0.341,0.127-0.532,0.116l-0.236,0.052l-9.119-1.607
c-1.135-0.198-1.895-1.281-1.693-2.416c0.198-1.135,1.281-1.895,2.416-1.693l3.959,0.697c-2.007-3.36-3.232-7.247-3.232-11.438
C3.178,36.604,10.118,27.927,19.589,25.301z M69.549,57.648L69.549,57.648c1.135-0.202,2.218,0.554,2.42,1.689
c0.199,1.135-0.558,2.213-1.693,2.416l-9.119,1.607l-0.236-0.052c-0.191,0.015-0.345-0.075-0.532-0.116l-0.79-0.176l-0.131-0.206
c-0.041-0.037-0.105-0.019-0.146-0.06c-0.135-0.135-0.112-0.33-0.202-0.487l-0.378-0.595l-1.607-9.119
c-0.199-1.135,0.558-2.213,1.693-2.416c1.135-0.199,2.213,0.558,2.416,1.693l0.775,4.404c1.64-2.734,2.64-5.895,2.64-9.322
c0.003-8.385-5.663-15.453-13.363-17.587c-1.112-0.307-1.76-1.457-1.453-2.565c0.307-1.112,1.457-1.76,2.565-1.453
c9.471,2.625,16.411,11.303,16.415,21.605c0,4.191-1.225,8.079-3.232,11.438L69.549,57.648z M41.772,20.352l-4.565-4.566
l0.004,28.939l4.565-4.565c0.813-0.813,2.135-0.813,2.947,0c0.813,0.813,0.813,2.131,0,2.947L36.6,51.23
c-0.378,0.378-0.899,0.61-1.476,0.61c-0.577,0-1.097-0.232-1.476-0.61l-8.157-8.157c-0.813-0.813-0.813-2.135,0-2.947
c0.813-0.813,2.131-0.813,2.947,0l4.599,4.599V15.719l-4.599,4.599c-0.813,0.813-2.135,0.813-2.947,0
c-0.813-0.813-0.813-2.135,0-2.947l8.123-8.123c0.412-0.412,0.951-0.607,1.491-0.603c0.004,0,0.007-0.007,0.015-0.007
c0.599,0,1.12,0.262,1.498,0.667l8.101,8.101c0.813,0.813,0.813,2.135,0,2.947C43.907,21.164,42.585,21.164,41.772,20.352z"/>
</svg>
<svg width="72" height="756" viewBox="0 0 72 756" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M36 0V108" stroke="#9F0B10" stroke-width="3" stroke-miterlimit="10"/>
<path d="M18 108H54" stroke="white" stroke-width="6" stroke-miterlimit="10"/>
<path d="M18 324H54" stroke="white" stroke-width="6" stroke-miterlimit="10"/>
<path d="M18 540H54" stroke="white" stroke-width="6" stroke-miterlimit="10"/>
<path d="M18 753H54" stroke="white" stroke-width="6" stroke-miterlimit="10"/>
<path d="M18 3H54" stroke="#9F0B10" stroke-width="6" stroke-miterlimit="10"/>
<path d="M18 216H54" stroke="white" stroke-width="6" stroke-miterlimit="10"/>
<path d="M18 432H54" stroke="white" stroke-width="6" stroke-miterlimit="10"/>
<path d="M18 648H54" stroke="white" stroke-width="6" stroke-miterlimit="10"/>
</svg>
<svg width="72" height="756" viewBox="0 0 72 756" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M36 0V108" stroke="#C92A30" stroke-width="3" stroke-miterlimit="10"/>
<path d="M18 108H54" stroke="#212529" stroke-width="6" stroke-miterlimit="10"/>
<path d="M18 324H54" stroke="#212529" stroke-width="6" stroke-miterlimit="10"/>
<path d="M18 540H54" stroke="#212529" stroke-width="6" stroke-miterlimit="10"/>
<path d="M18 753H54" stroke="#212529" stroke-width="6" stroke-miterlimit="10"/>
<path d="M18 3H54" stroke="#9F0B10" stroke-width="6" stroke-miterlimit="10"/>
<path d="M18 216H54" stroke="#212529" stroke-width="6" stroke-miterlimit="10"/>
<path d="M18 432H54" stroke="#212529" stroke-width="6" stroke-miterlimit="10"/>
<path d="M18 648H54" stroke="#212529" stroke-width="6" stroke-miterlimit="10"/>
</svg>
<svg width="72" height="756" viewBox="0 0 72 756" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M36 0V108" stroke="#E03131" stroke-width="3" stroke-miterlimit="10"/>
<path d="M18 108H54" stroke="white" stroke-width="6" stroke-miterlimit="10"/>
<path d="M18 324H54" stroke="white" stroke-width="6" stroke-miterlimit="10"/>
<path d="M18 540H54" stroke="white" stroke-width="6" stroke-miterlimit="10"/>
<path d="M18 753H54" stroke="white" stroke-width="6" stroke-miterlimit="10"/>
<path d="M18 3H54" stroke="#E03131" stroke-width="6" stroke-miterlimit="10"/>
<path d="M18 216H54" stroke="white" stroke-width="6" stroke-miterlimit="10"/>
<path d="M18 432H54" stroke="white" stroke-width="6" stroke-miterlimit="10"/>
<path d="M18 648H54" stroke="white" stroke-width="6" stroke-miterlimit="10"/>
</svg>
<svg width="72" height="72" viewBox="0 0 72 72" fill="none" xmlns="http://www.w3.org/2000/svg">
<path d="M36 44.6C41.3478 44.6 45.683 40.4094 45.683 35.24C45.683 30.0706 41.3478 25.88 36 25.88C30.6522 25.88 26.317 30.0706 26.317 35.24C26.317 40.4094 30.6522 44.6 36 44.6Z" fill="#07916D"/>
<path fill-rule="evenodd" clip-rule="evenodd" d="M14.4 1.40002H57.6L45.387 37.548L26.585 37.434L14.4 1.40002Z" fill="url(#paint0_linear)"/>
<defs>
<linearGradient id="paint0_linear" x1="36.0008" y1="1.82077" x2="36.0008" y2="37.5507" gradientUnits="userSpaceOnUse">
<stop stop-color="#0CA678" stop-opacity="0"/>
<stop offset="1" stop-color="#07916D"/>
</linearGradient>
</defs>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.4, 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>
<g>
<path class="st0" d="M53.3,245.5c-3.1,3.1-7.7,3.1-10.8,0c-3.1-3.1-3.1-7.7,0-10.8l17-17C44,200,34,176.8,32.4,151.3H7.7
c-4.6,0-7.7-3.1-7.7-7.7c0-3.9,3.1-7.7,7.7-7.7h24.7C34,111.2,44,88,59.5,70.3l-17-17c-3.1-3.1-3.1-7.7,0-10.8
c3.1-3.1,7.7-3.1,10.8,0l17,17C88,44,111.2,34,135.9,32.4V7.7c0-4.6,3.9-7.7,7.7-7.7c4.6,0,7.7,3.1,7.7,7.7v24.7
c25.5,1.5,48.6,11.6,66.4,27l17-17c3.1-3.1,7.7-3.1,10.8,0c3.1,3.1,3.1,7.7,0,10.8l-17,17c15.4,17.8,25.5,40.9,27,65.6h24.7
c3.9,0,7.7,3.9,7.7,7.7c0,4.6-3.9,7.7-7.7,7.7h-24.7c-1.5,25.5-11.6,48.6-27,66.4l17,17c3.1,3.1,3.1,7.7,0,10.8
c-3.1,3.1-7.7,3.1-10.8,0l-17-17c-17.8,15.4-40.9,25.5-66.4,27v24.7c0,3.9-3.1,7.7-7.7,7.7c-3.9,0-7.7-3.9-7.7-7.7v-24.7
c-24.7-1.5-47.9-11.6-65.6-27L53.3,245.5z M143.6,47.9c-53.3,0-96.5,42.5-96.5,95.7c0,54,43.2,96.5,96.5,96.5
c54,0,96.5-42.5,96.5-96.5C240.1,90.3,197.7,47.9,143.6,47.9z"/>
<circle class="st0" cx="144" cy="144" r="72"/>
</g>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.4, 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="M79.2,0h-72C5.3,0,3.5,0.8,2.1,2.1C0.8,3.5,0,5.3,0,7.2v273.6c0,1.9,0.8,3.8,2.1,5.1c1.4,1.4,3.2,2.1,5.1,2.1
h72c1.9,0,3.7-0.8,5.1-2.1c1.4-1.3,2.1-3.2,2.1-5.1V7.2c0-1.9-0.8-3.8-2.1-5.1C82.9,0.8,81.1,0,79.2,0z M43.2,259.2
c-5.8,0-11.1-3.5-13.3-8.9c-2.2-5.4-1-11.6,3.1-15.7c4.1-4.1,10.3-5.3,15.7-3.1c5.4,2.2,8.9,7.5,8.9,13.3
C57.6,252.7,51.2,259.2,43.2,259.2L43.2,259.2z"/>
<path class="st0" d="M280.8,201.6h-63l-117,67.6V288h180c1.9,0,3.8-0.8,5.1-2.1c1.4-1.4,2.1-3.2,2.1-5.1v-72c0-1.9-0.8-3.7-2.1-5.1
C284.5,202.4,282.7,201.6,280.8,201.6L280.8,201.6z"/>
<path class="st0" d="M130.3,235.5L278,150.2c3.4-2,4.6-6.4,2.6-9.8l-36-62.4v0c-2-3.4-6.4-4.6-9.8-2.6l-18.1,10.4L130.3,235.5z"/>
<path class="st0" d="M219.6,37.6l-62.4-36c-3.4-2-7.8-0.8-9.8,2.6L100.8,85v172.8L222.2,47.5c1-1.6,1.2-3.6,0.7-5.5
C222.5,40.1,221.3,38.6,219.6,37.6L219.6,37.6z"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.4, 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:none;stroke:#FFFFFF;stroke-width:8;}
.st1{fill:#FFFFFF;stroke:#FFFFFF;}
</style>
<rect x="3.6" y="40.7" class="st0" width="280.8" height="206.6"/>
<rect x="122.3" y="144.5" class="st1" width="162.1" height="102.8"/>
</svg>
<?xml version="1.0" encoding="utf-8"?>
<!-- Generator: Adobe Illustrator 23.0.4, 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:none;stroke:#FFFFFF;stroke-width:8;}
</style>
<rect x="3.6" y="40.7" class="st0" width="280.8" height="206.6"/>
</svg>
/****************************************************************************
*
* (c) 2009-2019 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.
*
* @file
* @author Gus Grubba <gus@auterion.com>
*/
import QtQuick 2.11
import QtQuick.Controls 1.2
import QGroundControl 1.0
import QGroundControl.MultiVehicleManager 1.0
import QGroundControl.Controls 1.0
import QGroundControl.Palette 1.0
import QGroundControl.ScreenTools 1.0
//-------------------------------------------------------------------------
//-- Armed Indicator
Rectangle {
anchors.top: parent.top
anchors.bottom: parent.bottom
width: labelRow.width + (ScreenTools.defaultFontPixelWidth * 6)
color: qgcPal.windowShade
property bool _armed: activeVehicle ? activeVehicle.armed : false
Row {
id: labelRow
spacing: ScreenTools.defaultFontPixelWidth
anchors.centerIn: parent
QGCLabel {
id: labelText
text: _armed ? qsTr("Armed") : qsTr("Disarmed")
color: qgcPal.text
font.pointSize: ScreenTools.defaultFontPointSize
anchors.verticalCenter: parent.verticalCenter
}
Rectangle {
height: ScreenTools.defaultFontPixelHeight * 0.5
width: height
radius: height * 0.5
color: _armed ? qgcPal.colorGreen : qgcPal.colorRed
border.color: qgcPal.window
border.width: 1
anchors.verticalCenter: parent.verticalCenter
}
}
QGCMouseArea {
fillItem: parent
onClicked: _armed ? mainWindow.disarmVehicle() : mainWindow.armVehicle()
}
}
/****************************************************************************
*
* (c) 2009-2019 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.
*
* @file
* @author Gus Grubba <gus@auterion.com>
*/
import QtQuick 2.11
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.11
import QGroundControl 1.0
import QGroundControl.Controls 1.0
import QGroundControl.MultiVehicleManager 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.Palette 1.0
//-------------------------------------------------------------------------
//-- Battery Indicator
Item {
id: _root
width: batteryIndicatorRow.width
anchors.top: parent.top
anchors.bottom: parent.bottom
property var battery1: activeVehicle ? activeVehicle.battery : null
property var battery2: activeVehicle ? activeVehicle.battery2 : null
property bool hasSecondBattery: battery2 && battery2.voltage.value !== -1
function lowestBattery() {
if(activeVehicle) {
if(hasSecondBattery) {
if(activeVehicle.battery2.percentRemaining.value < activeVehicle.battery.percentRemaining.value) {
return activeVehicle.battery2
}
}
return activeVehicle.battery
}
return null
}
function getBatteryColor(battery) {
if(battery) {
if(battery.percentRemaining.value > 75) {
return qgcPal.text
}
if(battery.percentRemaining.value > 50) {
return qgcPal.colorOrange
}
if(battery.percentRemaining.value > 0.1) {
return qgcPal.colorRed
}
}
return qgcPal.colorGrey
}
function getBatteryPercentageText(battery) {
if(battery) {
if(battery.percentRemaining.value > 98.9) {
return "100%"
}
if(battery.percentRemaining.value > 0.1) {
return battery.percentRemaining.valueString + battery.percentRemaining.units
}
if(battery.voltage.value >= 0) {
return battery.voltage.valueString + battery.voltage.units
}
}
return "N/A"
}
Component {
id: batteryInfo
Rectangle {
width: battCol.width + ScreenTools.defaultFontPixelWidth * 3
height: battCol.height + ScreenTools.defaultFontPixelHeight * 2
radius: ScreenTools.defaultFontPixelHeight * 0.5
color: qgcPal.window
Column {
id: battCol
spacing: ScreenTools.defaultFontPixelHeight * 0.5
width: Math.max(battGrid.width, battLabel.width)
anchors.margins: ScreenTools.defaultFontPixelHeight
anchors.centerIn: parent
QGCLabel {
id: battLabel
text: qsTr("Battery Status")
font.family: ScreenTools.demiboldFontFamily
anchors.horizontalCenter: parent.horizontalCenter
}
GridLayout {
id: battGrid
anchors.margins: ScreenTools.defaultFontPixelHeight
columnSpacing: ScreenTools.defaultFontPixelWidth
columns: 2
anchors.horizontalCenter: parent.horizontalCenter
QGCLabel {
id: batteryLabel
text: qsTr("Battery 1")
Layout.alignment: Qt.AlignVCenter
}
QGCColoredImage {
height: batteryLabel.height
width: height
sourceSize.width: width
source: "/qmlimages/Battery.svg"
color: qgcPal.text
fillMode: Image.PreserveAspectFit
Rectangle {
color: getBatteryColor(activeVehicle ? activeVehicle.battery : null)
anchors.left: parent.left
anchors.leftMargin: ScreenTools.defaultFontPixelWidth * 0.125
height: parent.height * 0.35
width: activeVehicle ? (activeVehicle.battery.percentRemaining.value / 100) * parent.width * 0.875 : 0
anchors.verticalCenter: parent.verticalCenter
}
}
QGCLabel { text: qsTr("Voltage:") }
QGCLabel { text: (battery1 && battery1.voltage.value !== -1) ? (battery1.voltage.valueString + " " + battery1.voltage.units) : "N/A" }
QGCLabel { text: qsTr("Accumulated Consumption:") }
QGCLabel { text: (battery1 && battery1.mahConsumed.value !== -1) ? (battery1.mahConsumed.valueString + " " + battery1.mahConsumed.units) : "N/A" }
Item {
width: 1
height: 1
visible: hasSecondBattery;
Layout.columnSpan: 2
}
QGCLabel {
text: qsTr("Battery 2")
visible: hasSecondBattery
Layout.alignment: Qt.AlignVCenter
}
QGCColoredImage {
height: batteryLabel.height
width: height
sourceSize.width: width
source: "/qmlimages/Battery.svg"
color: qgcPal.text
visible: hasSecondBattery
fillMode: Image.PreserveAspectFit
Rectangle {
color: getBatteryColor(activeVehicle ? activeVehicle.battery2 : null)
anchors.left: parent.left
anchors.leftMargin: ScreenTools.defaultFontPixelWidth * 0.125
height: parent.height * 0.35
width: activeVehicle ? (activeVehicle.battery2.percentRemaining.value / 100) * parent.width * 0.875 : 0
anchors.verticalCenter: parent.verticalCenter
}
}
QGCLabel { text: qsTr("Voltage:"); visible: hasSecondBattery; }
QGCLabel { text: (battery2 && battery2.voltage.value !== -1) ? (battery2.voltage.valueString + " " + battery2.voltage.units) : "N/A"; visible: hasSecondBattery; }
QGCLabel { text: qsTr("Accumulated Consumption:"); visible: hasSecondBattery; }
QGCLabel { text: (battery2 && battery2.mahConsumed.value !== -1) ? (battery2.mahConsumed.valueString + " " + battery2.mahConsumed.units) : "N/A"; visible: hasSecondBattery; }
}
}
}
}
Row {
id: batteryIndicatorRow
anchors.top: parent.top
anchors.bottom: parent.bottom
opacity: (activeVehicle && activeVehicle.battery.voltage.value >= 0) ? 1 : 0.5
spacing: ScreenTools.defaultFontPixelWidth
QGCColoredImage {
anchors.top: parent.top
anchors.bottom: parent.bottom
width: height
sourceSize.width: width
source: "/qmlimages/Battery.svg"
color: qgcPal.text
fillMode: Image.PreserveAspectFit
Rectangle {
color: getBatteryColor(lowestBattery())
anchors.left: parent.left
anchors.leftMargin: ScreenTools.defaultFontPixelWidth * 0.25
height: parent.height * 0.35
width: activeVehicle ? (activeVehicle.battery.percentRemaining.value / 100) * parent.width * 0.75 : 0
anchors.verticalCenter: parent.verticalCenter
}
}
QGCLabel {
text: getBatteryPercentageText(lowestBattery())
font.pointSize: ScreenTools.smallFontPointSize
color: getBatteryColor(lowestBattery())
anchors.verticalCenter: parent.verticalCenter
}
}
MouseArea {
anchors.fill: parent
onClicked: {
mainWindow.showPopUp(_root, batteryInfo)
}
}
}
/****************************************************************************
*
* (c) 2009-2019 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.
*
* @file
* @author Gus Grubba <gus@auterion.com>
*/
import QtQuick 2.11
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.11
import QGroundControl 1.0
import QGroundControl.Controls 1.0
import QGroundControl.MultiVehicleManager 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.Palette 1.0
import Custom.Widgets 1.0
//-------------------------------------------------------------------------
//-- GPS Indicator
Item {
id: _root
width: gpsRow.width
anchors.top: parent.top
anchors.bottom: parent.bottom
function getGPSSignal() {
if(!activeVehicle || activeVehicle.gps.count.rawValue < 1 || activeVehicle.gps.hdop.rawValue > 1.4) {
return 0;
} else if(activeVehicle.gps.hdop.rawValue < 1.0) {
return 100;
} else if(activeVehicle.gps.hdop.rawValue < 1.1) {
return 75;
} else if(activeVehicle.gps.hdop.rawValue < 1.2) {
return 50;
} else {
return 25;
}
}
Component {
id: gpsInfo
Rectangle {
width: gpsCol.width + ScreenTools.defaultFontPixelWidth * 3
height: gpsCol.height + ScreenTools.defaultFontPixelHeight * 2
radius: ScreenTools.defaultFontPixelHeight * 0.5
color: qgcPal.window
Column {
id: gpsCol
spacing: ScreenTools.defaultFontPixelHeight * 0.5
width: Math.max(gpsGrid.width, gpsLabel.width)
anchors.margins: ScreenTools.defaultFontPixelHeight
anchors.centerIn: parent
QGCLabel {
id: gpsLabel
text: (activeVehicle && activeVehicle.gps.count.value >= 0) ? qsTr("GPS Status") : qsTr("GPS Data Unavailable")
font.family: ScreenTools.demiboldFontFamily
anchors.horizontalCenter: parent.horizontalCenter
}
GridLayout {
id: gpsGrid
visible: (activeVehicle && activeVehicle.gps.count.value >= 0)
anchors.margins: ScreenTools.defaultFontPixelHeight
columnSpacing: ScreenTools.defaultFontPixelWidth
anchors.horizontalCenter: parent.horizontalCenter
columns: 2
QGCLabel { text: qsTr("GPS Count:") }
QGCLabel { text: activeVehicle ? activeVehicle.gps.count.valueString : qsTr("N/A", "No data to display") }
QGCLabel { text: qsTr("GPS Lock:") }
QGCLabel { text: activeVehicle ? activeVehicle.gps.lock.enumStringValue : qsTr("N/A", "No data to display") }
QGCLabel { text: qsTr("HDOP:") }
QGCLabel { text: activeVehicle ? activeVehicle.gps.hdop.valueString : qsTr("--.--", "No data to display") }
QGCLabel { text: qsTr("VDOP:") }
QGCLabel { text: activeVehicle ? activeVehicle.gps.vdop.valueString : qsTr("--.--", "No data to display") }
QGCLabel { text: qsTr("Course Over Ground:") }
QGCLabel { text: activeVehicle ? activeVehicle.gps.courseOverGround.valueString : qsTr("--.--", "No data to display") }
}
}
}
}
Row {
id: gpsRow
anchors.top: parent.top
anchors.bottom: parent.bottom
spacing: ScreenTools.defaultFontPixelWidth * 0.25
QGCColoredImage {
width: height
anchors.top: parent.top
anchors.bottom: parent.bottom
sourceSize.height: height
source: "/qmlimages/Gps.svg"
color: qgcPal.text
fillMode: Image.PreserveAspectFit
opacity: getGPSSignal() > 0 ? 1 : 0.5
}
CustomSignalStrength {
anchors.verticalCenter: parent.verticalCenter
size: parent.height * 0.75
percent: getGPSSignal()
}
}
MouseArea {
anchors.fill: parent
onClicked: {
mainWindow.showPopUp(_root, gpsInfo)
}
}
}
/****************************************************************************
*
* (c) 2009-2019 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.
*
* @file
* @author Gus Grubba <gus@auterion.com>
*/
import QtQuick 2.11
import QtQuick.Controls 2.4
import QtQuick.Layouts 1.11
import QGroundControl 1.0
import QGroundControl.Controls 1.0
import QGroundControl.Palette 1.0
import QGroundControl.MultiVehicleManager 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.Controllers 1.0
import Custom.Widgets 1.0
Item {
id: toolBar
anchors.fill: parent
property string sectionTitle: qsTr("Fly")
property bool inPlanView: planViewLoader.visible
property bool inFlyView: rootBackground.visible
property color menuSeparatorColor: qgcPal.globalTheme === QGCPalette.Light ? Qt.rgba(0,0,0,0.25) : Qt.rgba(1,1,1,0.25)
//-------------------------------------------------------------------------
//-- Setup can be invoked from c++ side
Connections {
target: setupWindow
onVisibleChanged: {
if(setupWindow.visible) {
vehicleSetup.checked = true
sectionTitle = vehicleSetup.text
}
}
}
//-------------------------------------------------------------------------
//-- Initial State
Component.onCompleted: {
flyButton.checked = true
sectionTitle = flyButton.text
}
//-------------------------------------------------------------------------
//-- Fly/Plan state toggle
onInPlanViewChanged: {
if(inPlanView) {
planButton.checked = true
sectionTitle = planButton.text
}
}
onInFlyViewChanged: {
if(inFlyView) {
flyButton.checked = true
sectionTitle = flyButton.text
}
}
Row {
id: iconRow
height: parent.height
anchors.left: parent.left
spacing: ScreenTools.defaultFontPixelWidth * 2
CustomIconButton {
height: parent.height
onPressed: {
if(drawer.visible) {
drawer.close()
} else {
drawer.open()
}
// Easter egg mechanism
_pressCount++
eggTimer.restart()
if (_pressCount == 5) {
QGroundControl.corePlugin.showAdvancedUI = !QGroundControl.corePlugin.showAdvancedUI
}
}
property int _pressCount: 0
Timer {
id: eggTimer
interval: 1000
onTriggered: parent._pressCount = 0
}
}
Rectangle {
width: 1
height: parent.height
color: qgcPal.globalTheme === QGCPalette.Light ? Qt.rgba(0,0,0,0.15) : Qt.rgba(1,1,1,0.15)
}
//-------------------------------------------------------------------------
//-- Multi Vehicle Selector
Loader {
anchors.top: parent.top
anchors.bottom: parent.bottom
source: "/custom/CustomMultiVehicleSelector.qml"
visible: activeVehicle && !inPlanView
}
Rectangle {
width: 1
height: parent.height
color: menuSeparatorColor
visible: activeVehicle && !inPlanView
}
//-------------------------------------------------------------------------
//-- Flight Mode
Loader {
anchors.top: parent.top
anchors.bottom: parent.bottom
source: "/custom/CustomModeIndicator.qml"
visible: activeVehicle && !inPlanView
}
}
//-------------------------------------------------------------------------
//-- Arm/Disarm
Loader {
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
source: "/custom/CustomArmedIndicator.qml"
visible: activeVehicle && !inPlanView
}
//-------------------------------------------------------------------------
// Indicators
Loader {
source: inPlanView ? "/qml/PlanToolBarIndicators.qml" : "/custom/CustomMainToolBarIndicators.qml"
anchors.left: iconRow.right
anchors.leftMargin: ScreenTools.defaultFontPixelWidth * 2
anchors.right: parent.right
anchors.top: parent.top
anchors.bottom: parent.bottom
}
//-------------------------------------------------------------------------
// Parameter download progress bar
Rectangle {
anchors.bottom: parent.bottom
height: ScreenTools.defaultFontPixelheight * 0.25
width: activeVehicle ? activeVehicle.parameterManager.loadProgress * parent.width : 0
color: qgcPal.colorGreen
}
//-------------------------------------------------------------------------
// Bottom single pixel divider
Rectangle {
anchors.left: parent.left
anchors.right: parent.right
anchors.bottom: parent.bottom
height: 1
color: menuSeparatorColor
}
//-------------------------------------------------------------------------
//-- Navigation Drawer (Left to Right, on command or using touch gestures)
Drawer {
id: drawer
y: header.height
width: navButtonWidth
height: mainWindow.height - header.height
closePolicy: Popup.CloseOnEscape | Popup.CloseOnPressOutside
background: Rectangle {
color: qgcPal.window
}
ButtonGroup {
id: buttonGroup
buttons: buttons.children
}
ColumnLayout {
id: buttons
spacing: 0
anchors.top: parent.top
anchors.left: parent.left
anchors.right: parent.right
Rectangle {
Layout.alignment: Qt.AlignVCenter
width: parent.width
height: 1
color: menuSeparatorColor
}
CustomToolBarButton {
id: flyButton
spacing: 1
text: qsTr("Fly")
icon.source: "/qmlimages/PaperPlane.svg"
Layout.fillWidth: true
onClicked: {
checked = true
drawer.close()
sectionTitle = text
mainWindow.showFlyView()
}
}
Rectangle {
Layout.alignment: Qt.AlignVCenter
width: parent.width
height: 1
color: menuSeparatorColor
}
CustomToolBarButton {
id: planButton
text: qsTr("Plan")
icon.source: "/qmlimages/Plan.svg"
Layout.fillWidth: true
onClicked: {
checked = true
drawer.close()
sectionTitle = text
mainWindow.showPlanView()
}
}
Rectangle {
Layout.alignment: Qt.AlignVCenter
width: parent.width
height: 1
color: menuSeparatorColor
}
CustomToolBarButton {
text: qsTr("Analyze")
icon.source: "/qmlimages/Analyze.svg"
Layout.fillWidth: true
onClicked: {
checked = true
drawer.close()
sectionTitle = text
mainWindow.showAnalyzeView()
}
}
Rectangle {
Layout.alignment: Qt.AlignVCenter
width: parent.width
height: 1
color: menuSeparatorColor
}
CustomToolBarButton {
id: vehicleSetup
text: qsTr("Vehicle Setup")
icon.source: "/qmlimages/Gears.svg"
Layout.fillWidth: true
onClicked: {
checked = true
drawer.close()
sectionTitle = text
mainWindow.showSetupView()
}
}
Rectangle {
Layout.alignment: Qt.AlignVCenter
width: parent.width
height: 1
color: menuSeparatorColor
}
}
ColumnLayout {
id: lowerButtons
anchors.bottom: parent.bottom
anchors.left: parent.left
anchors.right: parent.right
spacing: 0
Rectangle {
Layout.alignment: Qt.AlignVCenter
width: parent.width
height: 1
color: menuSeparatorColor
}
CustomToolBarButton {
id: settingsButton
text: qsTr("Settings")
icon.source: "/qmlimages/Gears.svg"
Layout.fillWidth: true
onClicked: {
checked = true
buttonGroup.checkState = Qt.Unchecked
drawer.close()
sectionTitle = text
mainWindow.showSettingsView()
}
}
Connections {
target: buttonGroup
onClicked: settingsButton.checked = false
}
}
}
}
/****************************************************************************
*
* (c) 2009-2019 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.
*
* @file
* @author Gus Grubba <gus@auterion.com>
*/
import QtQuick 2.11
import QtQuick.Controls 2.4
import QtQuick.Dialogs 1.3
import QtQuick.Layouts 1.11
import QGroundControl 1.0
import QGroundControl.Controls 1.0
import QGroundControl.MultiVehicleManager 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.Palette 1.0
Item {
anchors.fill: parent
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
Row {
id: waitForVehicle
spacing: ScreenTools.defaultFontPixelWidth
visible: !activeVehicle
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.left: parent.left
QGCColoredImage {
id: menuEdge
anchors.verticalCenter: parent.verticalCenter
height: ScreenTools.defaultFontPixelHeight
width: height
sourceSize.height: parent.height
fillMode: Image.PreserveAspectFit
source: "/qmlimages/PaperPlane.svg"
color: qgcPal.buttonText
}
QGCLabel {
anchors.verticalCenter: parent.verticalCenter
text: qsTr("Waiting for a vehicle")
font.pointSize: ScreenTools.mediumFontPointSize
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 {
id: pairingLoader
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.margins: _indicatorMargins
source: "/custom/PairingIndicator.qml"
}
}
//-------------------------------------------------------------------------
//-- Toolbar Indicators
Row {
id: indicatorRow
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.right: parent.right
anchors.rightMargin: ScreenTools.defaultFontPixelWidth * 2
spacing: ScreenTools.defaultFontPixelWidth * 2
visible: activeVehicle && !communicationLost
Repeater {
model: activeVehicle ? activeVehicle.toolBarIndicators : []
Loader {
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.margins: _indicatorMargins
source: modelData;
}
}
Item {
width: 1
height: 1
}
Loader {
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.margins: _indicatorMargins
source: "/toolbar/MessageIndicator.qml"
}
}
}
/****************************************************************************
*
* (c) 2009-2019 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.
*
* @file
* @author Gus Grubba <gus@auterion.com>
*/
import QtQuick 2.11
import QtQuick.Controls 2.4
import QtQuick.Layouts 1.11
import QtQuick.Dialogs 1.3
import QGroundControl 1.0
import QGroundControl.Controls 1.0
import QGroundControl.MultiVehicleManager 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.Palette 1.0
//-------------------------------------------------------------------------
//-- Mode Indicator
Item {
anchors.top: parent.top
anchors.bottom: parent.bottom
width: selectorRow.width
Row {
id: selectorRow
spacing: ScreenTools.defaultFontPixelWidth
anchors.verticalCenter: parent.verticalCenter
QGCLabel {
id: flightModeSelector
text: activeVehicle ? activeVehicle.flightMode : qsTr("N/A")
color: qgcPal.text
font.pointSize: ScreenTools.defaultFontPointSize
anchors.verticalCenter: parent.verticalCenter
}
QGCColoredImage {
anchors.verticalCenter: parent.verticalCenter
height: ScreenTools.defaultFontPixelHeight * 0.5
width: height
sourceSize.height: parent.height
fillMode: Image.PreserveAspectFit
source: "/res/DropArrow.svg"
color: qgcPal.text
}
}
MouseArea {
visible: activeVehicle && activeVehicle.flightModeSetAvailable
anchors.fill: parent
onClicked: flightModesMenu.open()
}
//-------------------------------------------------------------------------
//-- Flight Modes
Popup {
id: flightModesMenu
width: Math.min(mainWindow.width * 0.666, ScreenTools.defaultFontPixelWidth * 40)
height: mainWindow.height * 0.5
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
property int selectedIndex: 0
background: Rectangle {
anchors.fill: parent
color: qgcPal.globalTheme === QGCPalette.Light ? Qt.rgba(1,1,1,0.95) : Qt.rgba(0,0,0,0.75)
border.color: qgcPal.text
radius: ScreenTools.defaultFontPixelWidth
}
ColumnLayout {
id: comboListCol
spacing: ScreenTools.defaultFontPixelHeight
anchors.centerIn: parent
QGCLabel {
text: qsTr("Flight Modes")
Layout.alignment: Qt.AlignHCenter
}
Repeater {
model: activeVehicle ? activeVehicle.flightModes : [ ]
QGCButton {
text: modelData
Layout.minimumHeight: ScreenTools.defaultFontPixelHeight * 3
Layout.minimumWidth: ScreenTools.defaultFontPixelWidth * 30
Layout.fillHeight: true
Layout.fillWidth: true
Layout.alignment: Qt.AlignHCenter
onClicked: {
activeVehicle.flightMode = modelData
flightModesMenu.close()
}
}
}
}
}
}
/****************************************************************************
*
* (c) 2009-2019 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.
*
* @file
* @author Gus Grubba <gus@auterion.com>
*/
import QtQuick 2.11
import QtQuick.Controls 1.4
import QGroundControl 1.0
import QGroundControl.Controls 1.0
import QGroundControl.MultiVehicleManager 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.Palette 1.0
//-------------------------------------------------------------------------
//-- Multi Vehicle Selector
Item {
anchors.top: parent.top
anchors.bottom: parent.bottom
width: selectorRow.width
property bool _multiVehicles: QGroundControl.multiVehicleManager.vehicles.count > 1
Component.onCompleted: {
updatemultiVehiclesMenu()
}
Connections {
target: QGroundControl.multiVehicleManager.vehicles
onCountChanged: updatemultiVehiclesMenu()
}
Row {
id: selectorRow
spacing: ScreenTools.defaultFontPixelWidth
anchors.verticalCenter: parent.verticalCenter
QGCColoredImage {
anchors.verticalCenter: parent.verticalCenter
height: ScreenTools.defaultFontPixelHeight
width: height
sourceSize.height: parent.height
fillMode: Image.PreserveAspectFit
source: "/qmlimages/PaperPlane.svg"
color: qgcPal.text
}
QGCLabel {
id: multiVehicleSelector
text: "Vehicle " + (activeVehicle ? activeVehicle.id : "None")
color: qgcPal.buttonText
anchors.verticalCenter: parent.verticalCenter
}
QGCColoredImage {
visible: _multiVehicles
anchors.verticalCenter: parent.verticalCenter
height: ScreenTools.defaultFontPixelHeight * 0.5
width: height
sourceSize.height: parent.height
fillMode: Image.PreserveAspectFit
source: "/res/DropArrow.svg"
color: qgcPal.text
}
}
Menu {
id: multiVehiclesMenu
}
Component {
id: multiVehicleMenuItemComponent
MenuItem {
onTriggered: QGroundControl.multiVehicleManager.activeVehicle = vehicle
property int vehicleId: Number(text.split(" ")[1])
property var vehicle: QGroundControl.multiVehicleManager.getVehicleById(vehicleId)
}
}
property var multiVehiclesMenuItems: []
function updatemultiVehiclesMenu() {
if (_multiVehicles) {
// Remove old menu items
for (var i = 0; i < multiVehiclesMenuItems.length; i++) {
multiVehiclesMenu.removeItem(multiVehiclesMenuItems[i])
}
multiVehiclesMenuItems.length = 0
// Add new items
for (i = 0; i < QGroundControl.multiVehicleManager.vehicles.count; i++) {
var vehicle = QGroundControl.multiVehicleManager.vehicles.get(i)
var menuItem = multiVehicleMenuItemComponent.createObject(null, { "text": "Vehicle " + vehicle.id })
multiVehiclesMenuItems.push(menuItem)
multiVehiclesMenu.insertItem(i, menuItem)
console.log("Vehicle " + vehicle.id)
}
} else {
console.log('No multiple vehicles: ' + QGroundControl.multiVehicleManager.vehicles.count)
}
}
MouseArea {
visible: _multiVehicles
anchors.fill: parent
onClicked: {
console.log('Clicked')
multiVehiclesMenu.popup()
}
}
}
/****************************************************************************
*
* (c) 2009-2019 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.
*
* @file
* @author Gus Grubba <gus@auterion.com>
*/
import QtQuick 2.11
import QtQuick.Controls 1.4
import QtQuick.Layouts 1.11
import QGroundControl 1.0
import QGroundControl.Controls 1.0
import QGroundControl.MultiVehicleManager 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.Palette 1.0
import Custom.Widgets 1.0
//-------------------------------------------------------------------------
//-- RC RSSI Indicator
Item {
id: _root
width: visible ? rssiRow.width : 0
anchors.top: parent.top
anchors.bottom: parent.bottom
visible: activeVehicle ? activeVehicle.supportsRadio : true
property bool _rcRSSIAvailable: activeVehicle ? activeVehicle.rcRSSI > 0 && activeVehicle.rcRSSI <= 100 : false
Component {
id: rcRSSIInfo
Rectangle {
width: rcrssiCol.width + ScreenTools.defaultFontPixelWidth * 3
height: rcrssiCol.height + ScreenTools.defaultFontPixelHeight * 2
radius: ScreenTools.defaultFontPixelHeight * 0.5
color: qgcPal.window
Column {
id: rcrssiCol
spacing: ScreenTools.defaultFontPixelHeight * 0.5
width: Math.max(rcrssiGrid.width, rssiLabel.width)
anchors.margins: ScreenTools.defaultFontPixelHeight
anchors.centerIn: parent
QGCLabel {
id: rssiLabel
text: activeVehicle ? (activeVehicle.rcRSSI !== 255 ? qsTr("RC RSSI Status") : qsTr("RC RSSI Data Unavailable")) : qsTr("N/A", "No data available")
font.family: ScreenTools.demiboldFontFamily
anchors.horizontalCenter: parent.horizontalCenter
}
GridLayout {
id: rcrssiGrid
visible: _rcRSSIAvailable
anchors.margins: ScreenTools.defaultFontPixelHeight
columnSpacing: ScreenTools.defaultFontPixelWidth
columns: 2
anchors.horizontalCenter: parent.horizontalCenter
QGCLabel { text: qsTr("RSSI:") }
QGCLabel { text: activeVehicle ? (activeVehicle.rcRSSI + "%") : 0 }
}
}
}
}
Row {
id: rssiRow
anchors.top: parent.top
anchors.bottom: parent.bottom
spacing: ScreenTools.defaultFontPixelWidth * 0.25
QGCColoredImage {
width: height
anchors.top: parent.top
anchors.bottom: parent.bottom
sourceSize.height: height
source: "/custom/img/menu_rc.svg"
color: qgcPal.text
fillMode: Image.PreserveAspectFit
opacity: _rcRSSIAvailable ? 1 : 0.5
}
CustomSignalStrength {
anchors.verticalCenter: parent.verticalCenter
size: parent.height * 0.75
percent: _rcRSSIAvailable ? activeVehicle.rcRSSI : 0
}
}
MouseArea {
anchors.fill: parent
onClicked: {
mainWindow.showPopUp(_root, rcRSSIInfo)
}
}
}
/****************************************************************************
*
* (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.11
import QtQuick.Controls 2.4
import QtQuick.Layouts 1.11
import QtQuick.Dialogs 1.3
import QGroundControl 1.0
import QGroundControl.Controls 1.0
import QGroundControl.MultiVehicleManager 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.Palette 1.0
//-------------------------------------------------------------------------
//-- GPS Indicator
Item {
id: _root
width: pairingRow.width * 1.1
anchors.top: parent.top
anchors.bottom: parent.bottom
property bool _light: qgcPal.globalTheme === QGCPalette.Light && !activeVehicle
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 {
id: pairingRow
spacing: ScreenTools.defaultFontPixelWidth
anchors.top: parent.top
anchors.bottom: parent.bottom
anchors.horizontalCenter: parent.horizontalCenter
QGCColoredImage {
id: pairingIcon
height: parent.height
width: height
color: qgcPal.text
source: "/custom/img/PairingIcon.svg"
sourceSize.width: width
fillMode: Image.PreserveAspectFit
smooth: true
mipmap: true
antialiasing: true
anchors.verticalCenter: parent.verticalCenter
}
QGCLabel {
text: qsTr("Pair Vehicle")
width: !activeVehicle ? (ScreenTools.defaultFontPixelWidth * 12) : 0
visible: !activeVehicle
font.family: ScreenTools.demiboldFontFamily
anchors.verticalCenter: parent.verticalCenter
}
}
MouseArea {
anchors.fill: parent
onClicked: {
runPairing()
}
}
//-------------------------------------------------------------------------
//-- Microhard
Popup {
id: mhPopup
width: mhBody.width
height: mhBody.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: mhBody
width: mhCol.width + (ScreenTools.defaultFontPixelWidth * 8)
height: mhCol.height + (ScreenTools.defaultFontPixelHeight * 2)
anchors.centerIn: parent
Column {
id: mhCol
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 {
text: qsTr("To connect to your vehicle, please click on the pairing button in order to put the vehicle in discovery mode")
width: _contentWidth
wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignHCenter
anchors.horizontalCenter: parent.horizontalCenter
}
Item { width: 1; height: ScreenTools.defaultFontPixelHeight * 2; }
QGCColoredImage {
height: ScreenTools.defaultFontPixelHeight * 6
width: height
source: "/custom/img/PairingButton.svg"
sourceSize.height: height
fillMode: Image.PreserveAspectFit
mipmap: true
smooth: true
color: qgcPal.text
anchors.horizontalCenter: parent.horizontalCenter
}
Item { width: 1; height: ScreenTools.defaultFontPixelHeight * 2; }
QGCButton {
text: qsTr("Pair a Vehicle")
width: _contentWidth
anchors.horizontalCenter: parent.horizontalCenter
onClicked: {
mhPopup.close()
progressPopup.open()
QGroundControl.pairingManager.startMicrohardPairing();
}
}
Item { width: 1; height: 1; }
}
}
}
//-------------------------------------------------------------------------
//-- NFC
Popup {
id: nfcPopup
width: nfcBody.width
height: nfcBody.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: nfcBody
width: nfcCol.width + (ScreenTools.defaultFontPixelWidth * 8)
height: nfcCol.height + (ScreenTools.defaultFontPixelHeight * 2)
anchors.centerIn: parent
Column {
id: nfcCol
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; }
Rectangle {
width: _rectWidth
height: _rectHeight
color: Qt.rgba(0,0,0,0)
border.color: qgcPal.text
border.width: 1
anchors.horizontalCenter: parent.horizontalCenter
QGCLabel {
text: "Vehicle and Tablet Graphic"
anchors.centerIn: parent
}
}
Item { width: 1; height: 1; }
QGCLabel {
text: qsTr("Please make sure your vehicle is close to your Ground Station device")
width: _contentWidth
wrapMode: Text.WordWrap
horizontalAlignment: Text.AlignHCenter
anchors.horizontalCenter: parent.horizontalCenter
}
Item { width: 1; height: 1; }
QGCButton {
text: qsTr("Pair Via NFC")
width: _contentWidth
anchors.horizontalCenter: parent.horizontalCenter
onClicked: {
nfcPopup.close()
progressPopup.open()
QGroundControl.pairingManager.startNFCScan();
}
}
Item { width: 1; height: 1; }
}
}
}
//-------------------------------------------------------------------------
//-- Pairing/Connection Progress
Popup {
id: progressPopup
width: progressBody.width
height: progressBody.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: progressBody
width: progressCol.width + (ScreenTools.defaultFontPixelWidth * 8)
height: progressCol.height + (ScreenTools.defaultFontPixelHeight * 2)
anchors.centerIn: parent
Column {
id: progressCol
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
}
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; }
//-- Pairing/Connecting
Item { width: 1; height: ScreenTools.defaultFontPixelHeight * 3; visible: busyIndicator.visible; }
QGCColoredImage {
id: busyIndicator
height: ScreenTools.defaultFontPixelHeight * 4
width: height
source: "/qmlimages/MapSync.svg"
sourceSize.height: height
fillMode: Image.PreserveAspectFit
mipmap: true
smooth: true
color: qgcPal.text
visible: QGroundControl.pairingManager.pairingStatus === PairingManager.PairingActive || QGroundControl.pairingManager.pairingStatus === PairingManager.PairingConnecting
anchors.horizontalCenter: parent.horizontalCenter
RotationAnimation on rotation {
loops: Animation.Infinite
from: 360
to: 0
duration: 720
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 {
text: qsTr("List Of Available Devices")
visible: QGroundControl.pairingManager ? (QGroundControl.pairingManager.pairedDeviceNameList.length > 0 && !cancelButton.visible) : false
font.family: ScreenTools.demiboldFontFamily
}
Item { width: 1; height: 1; }
GridLayout {
columns: 3
visible: QGroundControl.pairingManager ? (QGroundControl.pairingManager.pairedDeviceNameList.length > 0 && !cancelButton.visible) : false
columnSpacing: ScreenTools.defaultFontPixelWidth
rowSpacing: ScreenTools.defaultFontPixelHeight * 0.25
anchors.horizontalCenter: parent.horizontalCenter
property var _pairModel: QGroundControl.pairingManager ? QGroundControl.pairingManager.pairedDeviceNameList : []
Repeater {
model: parent._pairModel
delegate: QGCLabel {
text: modelData
Layout.row: index
Layout.column: 0
Layout.minimumWidth:ScreenTools.defaultFontPixelWidth * 14
Layout.fillWidth: true
}
}
Repeater {
model: parent._pairModel
delegate: QGCButton {
text: qsTr("Connect")
Layout.row: index
Layout.column: 1
onClicked: {
QGroundControl.pairingManager.connectToPairedDevice(modelData)
connectionPopup.close()
progressPopup.open()
}
}
}
Repeater {
model: parent._pairModel
delegate: QGCColoredImage {
Layout.preferredWidth: ScreenTools.defaultFontPixelHeight * 1.5
Layout.preferredHeight: ScreenTools.defaultFontPixelHeight * 1.5
sourceSize.height: height
source: "/res/TrashDelete.svg"
color: qgcPal.colorRed
Layout.row: index
Layout.column: 2
MouseArea {
anchors.fill: parent
onClicked: {
removePrompt.open()
}
}
MessageDialog {
id: removePrompt
title: qsTr("Remove Paired Vehicle")
text: qsTr("Confirm removing %1?").arg(modelData)
standardButtons: StandardButton.Yes | StandardButton.No
onNo: removePrompt.close()
onYes: {
QGroundControl.pairingManager.removePairedDevice(modelData)
removePrompt.close()
}
}
}
}
}
Item { width: 1; height: _contentSpacing; }
QGCButton {
width: _contentWidth
text: qsTr("Close")
anchors.horizontalCenter: parent.horizontalCenter
onClicked: {
connectionPopup.close()
}
}
QGCButton {
text: qsTr("Pair Another")
width: _contentWidth
anchors.horizontalCenter: parent.horizontalCenter
onClicked: {
connectionPopup.close()
mhPopup.open()
}
}
Item { width: 1; height: 1; }
}
}
}
}
/****************************************************************************
*
* (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.3
import QtQuick.Controls 1.2
import QtQml.Models 2.1
import QGroundControl 1.0
import QGroundControl.ScreenTools 1.0
import QGroundControl.Controls 1.0
import QGroundControl.FlightDisplay 1.0
Rectangle {
width: mainColumn.width + ScreenTools.defaultFontPixelWidth * 3
height: mainColumn.height + ScreenTools.defaultFontPixelHeight
color: qgcPal.windowShade
radius: 3
PreFlightCheckModel {
id: listModel
PreFlightCheckGroup {
name: qsTr("Initial checks")
// Standard check list items (group 0) - Available from the start
PreFlightCheckButton {
name: qsTr("Hardware")
manualText: qsTr("Props mounted? Wings secured? Tail secured?")
}
PreFlightBatteryCheck {
failurePercent: 40
allowFailurePercentOverride: false
}
PreFlightSensorsHealthCheck {
}
PreFlightGPSCheck {
failureSatCount: 9
allowOverrideSatCount: true
}
PreFlightRCCheck {
}
}
PreFlightCheckGroup {
name: qsTr("Please arm the vehicle here")
PreFlightCheckButton {
name: qsTr("Actuators")
manualText: qsTr("Move all control surfaces. Did they work properly?")
}
PreFlightCheckButton {
name: qsTr("Motors")
manualText: qsTr("Propellers free? Then throttle up gently. Working properly?")
}
PreFlightCheckButton {
name: qsTr("Mission")
manualText: qsTr("Please confirm mission is valid (waypoints valid, no terrain collision).")
}
PreFlightSoundCheck {
}
}
PreFlightCheckGroup {
name: qsTr("Last preparations before launch")
// Check list item group 2 - Final checks before launch
PreFlightCheckButton {
name: qsTr("Payload")
manualText: qsTr("Configured and started? Payload lid closed?")
}
PreFlightCheckButton {
name: "Wind & weather"
manualText: qsTr("OK for your platform? Lauching into the wind?")
}
PreFlightCheckButton {
name: qsTr("Flight area")
manualText: qsTr("Launch area and path free of obstacles/people?")
}
}
}
property bool _passed: false
function _handleGroupPassedChanged(index, passed) {
if (passed) {
// Collapse current group
var group = checkListRepeater.itemAt(index)
group._checked = false
// Expand next group
if (index + 1 < checkListRepeater.count) {
group = checkListRepeater.itemAt(index + 1)
group.enabled = true
group._checked = true
}
}
_passed = passed
}
// We delay the updates when a group passes so the user can see all items green for a moment prior to hiding
Timer {
id: delayedGroupPassed
interval: 750
property int index
onTriggered: _handleGroupPassedChanged(index, true /* passed */)
}
Column {
id: mainColumn
width: 40 * ScreenTools.defaultFontPixelWidth
spacing: 0.8 * ScreenTools.defaultFontPixelWidth
anchors.left: parent.left
anchors.top: parent.top
anchors.topMargin: 0.6 * ScreenTools.defaultFontPixelWidth
anchors.leftMargin: 1.5 * ScreenTools.defaultFontPixelWidth
function groupPassedChanged(index, passed) {
if (passed) {
delayedGroupPassed.index = index
delayedGroupPassed.restart()
} else {
_handleGroupPassedChanged(index, passed)
}
}
// Header/title of checklist
Item {
width: parent.width
height: 1.75 * ScreenTools.defaultFontPixelHeight
QGCLabel {
text: qsTr("Pre-Flight Checklist %1").arg(_passed ? qsTr("(passed)") : "")
anchors.left: parent.left
anchors.verticalCenter: parent.verticalCenter
font.pointSize: ScreenTools.mediumFontPointSize
}
QGCButton {
width: 1.2 * ScreenTools.defaultFontPixelHeight
height: 1.2 * ScreenTools.defaultFontPixelHeight
anchors.right: parent.right
anchors.verticalCenter: parent.verticalCenter
tooltip: qsTr("Reset the checklist (e.g. after a vehicle reboot)")
onClicked: model.reset()
QGCColoredImage {
source: "/qmlimages/MapSyncBlack.svg"
color: qgcPal.buttonText
anchors.fill: parent
}
}
}
// All check list items
Repeater {
id: checkListRepeater
model: listModel
}
}
}
......@@ -15,41 +15,36 @@
#include "QGCApplication.h"
#include "QGCCorePlugin.h"
//-----------------------------------------------------------------------------
CustomAutoPilotPlugin::CustomAutoPilotPlugin(Vehicle* vehicle, QObject* parent)
: PX4AutoPilotPlugin(vehicle, parent)
{
// Whenever we go on/out of advanced mode the available list of settings pages will change
connect(qgcApp()->toolbox()->corePlugin(), &QGCCorePlugin::showAdvancedUIChanged, this, &CustomAutoPilotPlugin::_advancedChanged);
}
//-----------------------------------------------------------------------------
void
CustomAutoPilotPlugin::_advancedChanged(bool)
// This signals that when Advanced Mode changes the list of Vehicle Settings page also changed
void CustomAutoPilotPlugin::_advancedChanged(bool)
{
_components.clear();
emit vehicleComponentsChanged();
}
//-----------------------------------------------------------------------------
const QVariantList&
CustomAutoPilotPlugin::vehicleComponents()
// This allows us to hide most Vehicle Setup pages unless we are in Advanced Mmode
const QVariantList& CustomAutoPilotPlugin::vehicleComponents()
{
if (_components.count() == 0 && !_incorrectParameterVersion) {
if (_vehicle) {
bool showAdvanced = qgcApp()->toolbox()->corePlugin()->showAdvancedUI();
qDebug() << "Loading components:" << showAdvanced;
if (_vehicle->parameterManager()->parametersReady()) {
if(showAdvanced) {
_airframeComponent = new AirframeComponent(_vehicle, this);
_airframeComponent->setupTriggerSignals();
_components.append(QVariant::fromValue(reinterpret_cast<VehicleComponent*>(_airframeComponent)));
}
if (!_vehicle->hilMode()) {
if (showAdvanced) {
_airframeComponent = new AirframeComponent(_vehicle, this);
_airframeComponent->setupTriggerSignals();
_components.append(QVariant::fromValue(reinterpret_cast<VehicleComponent*>(_airframeComponent)));
_sensorsComponent = new SensorsComponent(_vehicle, this);
_sensorsComponent->setupTriggerSignals();
_components.append(QVariant::fromValue(reinterpret_cast<VehicleComponent*>(_sensorsComponent)));
}
if(showAdvanced) {
_radioComponent = new PX4RadioComponent(_vehicle, this);
_radioComponent->setupTriggerSignals();
_components.append(QVariant::fromValue(reinterpret_cast<VehicleComponent*>(_radioComponent)));
......@@ -71,7 +66,7 @@ CustomAutoPilotPlugin::vehicleComponents()
_safetyComponent->setupTriggerSignals();
_components.append(QVariant::fromValue(reinterpret_cast<VehicleComponent*>(_safetyComponent)));
if(showAdvanced) {
if (showAdvanced) {
_tuningComponent = new PX4TuningComponent(_vehicle, this);
_tuningComponent->setupTriggerSignals();
_components.append(QVariant::fromValue(reinterpret_cast<VehicleComponent*>(_tuningComponent)));
......@@ -83,22 +78,9 @@ CustomAutoPilotPlugin::vehicleComponents()
_components.append(QVariant::fromValue(reinterpret_cast<VehicleComponent*>(_cameraComponent)));
}
}
//-- Is there an ESP8266 Connected?
if(_vehicle->parameterManager()->parameterExists(MAV_COMP_ID_UDP_BRIDGE, "SW_VER")) {
_esp8266Component = new ESP8266Component(_vehicle, this);
_esp8266Component->setupTriggerSignals();
_components.append(QVariant::fromValue(reinterpret_cast<VehicleComponent*>(_esp8266Component)));
}
} else {
qWarning() << "Call to vehicleCompenents prior to parametersReady";
}
if(_vehicle->parameterManager()->parameterExists(_vehicle->id(), "SLNK_RADIO_CHAN")) {
_syslinkComponent = new SyslinkComponent(_vehicle, this);
_syslinkComponent->setupTriggerSignals();
_components.append(QVariant::fromValue(reinterpret_cast<VehicleComponent*>(_syslinkComponent)));
}
} else {
qWarning() << "Internal error";
}
......
......@@ -15,15 +15,17 @@
#include "PX4AutoPilotPlugin.h"
#include "Vehicle.h"
/// Custom overrides from standard PX4AutoPilotPlugin implementation
class CustomAutoPilotPlugin : public PX4AutoPilotPlugin
{
Q_OBJECT
public:
CustomAutoPilotPlugin(Vehicle* vehicle, QObject* parent);
const QVariantList& vehicleComponents() override;
const QVariantList& vehicleComponents() final;
private slots:
void _advancedChanged (bool advanced);
private:
QVariantList _components;
......
......@@ -16,8 +16,6 @@
#include "MAVLinkLogManager.h"
#include "CustomPlugin.h"
#include "CustomQuickInterface.h"
#include "CustomVideoManager.h"
#include "MultiVehicleManager.h"
#include "QGCApplication.h"
......@@ -28,93 +26,72 @@
QGC_LOGGING_CATEGORY(CustomLog, "CustomLog")
CustomVideoReceiver::CustomVideoReceiver(QObject* parent)
: GstVideoReceiver(parent)
CustomOptions::CustomOptions(CustomPlugin*, QObject* parent)
: QGCOptions(parent)
{
}
CustomVideoReceiver::~CustomVideoReceiver()
// Firmware upgrade page is only shown in Advanced Mode.
bool CustomOptions::showFirmwareUpgrade() const
{
return qgcApp()->toolbox()->corePlugin()->showAdvancedUI();
}
//-----------------------------------------------------------------------------
static QObject*
customQuickInterfaceSingletonFactory(QQmlEngine*, QJSEngine*)
// This custom build does not support conecting multiple vehicles to it. This in turn simplifies various parts of the QGC ui.
bool CustomOptions::enableMultiVehicleList(void) const
{
qCDebug(CustomLog) << "Creating CustomQuickInterface instance";
CustomQuickInterface* pIFace = new CustomQuickInterface();
auto* pPlug = qobject_cast<CustomPlugin*>(qgcApp()->toolbox()->corePlugin());
if(pPlug) {
pIFace->init();
} else {
qCritical() << "Error obtaining instance of CustomPlugin";
}
return pIFace;
return false;
}
//-----------------------------------------------------------------------------
CustomOptions::CustomOptions(CustomPlugin*, QObject* parent)
: QGCOptions(parent)
// This allows you to show a custom overlay on the fly screen.
QUrl CustomOptions::flyViewOverlay(void) const
{
return QUrl::fromUserInput("qrc:/custom/CustomFlyViewOverlay.qml");
}
//-----------------------------------------------------------------------------
bool
CustomOptions::showFirmwareUpgrade() const
// The standard instrement widget is now show. Only the custom overlay is shown.
CustomInstrumentWidget* CustomOptions::instrumentWidget(void)
{
return qgcApp()->toolbox()->corePlugin()->showAdvancedUI();
return nullptr;
}
QColor
CustomOptions::toolbarBackgroundLight() const
// Normal QGC needs to work with an ESP8266 WiFi thing which is remarkably crappy. This in turns causes PX4 Pro calibration to fail
// quite often. There is a warning in regular QGC about this. Overriding the and returning true means that your custom vehicle has
// a reliable WiFi connection so don't show that warning.
bool CustomOptions::wifiReliableForCalibration(void) const
{
return CustomPlugin::_windowShadeEnabledLightColor;
return true;
}
QColor
CustomOptions::toolbarBackgroundDark() const
{
return CustomPlugin::_windowShadeEnabledDarkColor;
}
//-----------------------------------------------------------------------------
CustomPlugin::CustomPlugin(QGCApplication *app, QGCToolbox* toolbox)
: QGCCorePlugin(app, toolbox)
{
_pOptions = new CustomOptions(this, this);
_options = new CustomOptions(this, this);
_showAdvancedUI = false;
}
//-----------------------------------------------------------------------------
CustomPlugin::~CustomPlugin()
{
}
//-----------------------------------------------------------------------------
void
CustomPlugin::setToolbox(QGCToolbox* toolbox)
void CustomPlugin::setToolbox(QGCToolbox* toolbox)
{
QGCCorePlugin::setToolbox(toolbox);
qmlRegisterSingletonType<CustomQuickInterface>("CustomQuickInterface", 1, 0, "CustomQuickInterface", customQuickInterfaceSingletonFactory);
//-- Disable automatic logging
toolbox->mavlinkLogManager()->setEnableAutoStart(false);
toolbox->mavlinkLogManager()->setEnableAutoUpload(false);
// Allows us to be notified when the user goes in/out out advanced mode
connect(qgcApp()->toolbox()->corePlugin(), &QGCCorePlugin::showAdvancedUIChanged, this, &CustomPlugin::_advancedChanged);
}
//-----------------------------------------------------------------------------
void
CustomPlugin::_advancedChanged(bool changed)
void CustomPlugin::_advancedChanged(bool changed)
{
//-- We are now in "Advanced Mode" (or not)
emit _pOptions->showFirmwareUpgradeChanged(changed);
// Firmware Upgrade page is only show in Advanced mode
emit _options->showFirmwareUpgradeChanged(changed);
}
//-----------------------------------------------------------------------------
void
CustomPlugin::addSettingsEntry(const QString& title,
const char* qmlFile,
const char* iconFile/*= nullptr*/)
void CustomPlugin::_addSettingsEntry(const QString& title, const char* qmlFile, const char* iconFile)
{
Q_CHECK_PTR(qmlFile);
// 'this' instance will take ownership on the QmlComponentInfo instance
......@@ -130,118 +107,66 @@ QVariantList&
CustomPlugin::settingsPages()
{
if(_customSettingsList.isEmpty()) {
addSettingsEntry(tr("General"), "qrc:/qml/GeneralSettings.qml", "qrc:/res/gear-white.svg");
addSettingsEntry(tr("Comm Links"), "qrc:/qml/LinkSettings.qml", "qrc:/res/waves.svg");
addSettingsEntry(tr("Offline Maps"),"qrc:/qml/OfflineMap.qml", "qrc:/res/waves.svg");
#if defined(QGC_GST_MICROHARD_ENABLED)
addSettingsEntry(tr("Microhard"), "qrc:/qml/MicrohardSettings.qml");
#endif
#if defined(QGC_GST_TAISYNC_ENABLED)
addSettingsEntry(tr("Taisync"), "qrc:/qml/TaisyncSettings.qml");
#endif
#if defined(QGC_AIRMAP_ENABLED)
addSettingsEntry(tr("AirMap"), "qrc:/qml/AirmapSettings.qml");
#endif
addSettingsEntry(tr("MAVLink"), "qrc:/qml/MavlinkSettings.qml", " qrc:/res/waves.svg");
addSettingsEntry(tr("Console"), "qrc:/qml/QGroundControl/Controls/AppMessages.qml");
#if defined(QGC_ENABLE_QZXING)
addSettingsEntry(tr("Barcode Test"),"qrc:/custom/BarcodeReader.qml");
#endif
_addSettingsEntry(tr("General"), "qrc:/qml/GeneralSettings.qml", "qrc:/res/gear-white.svg");
_addSettingsEntry(tr("Comm Links"), "qrc:/qml/LinkSettings.qml", "qrc:/res/waves.svg");
_addSettingsEntry(tr("Offline Maps"),"qrc:/qml/OfflineMap.qml", "qrc:/res/waves.svg");
_addSettingsEntry(tr("MAVLink"), "qrc:/qml/MavlinkSettings.qml", "qrc:/res/waves.svg");
_addSettingsEntry(tr("Console"), "qrc:/qml/QGroundControl/Controls/AppMessages.qml");
#if defined(QT_DEBUG)
//-- These are always present on Debug builds
addSettingsEntry(tr("Mock Link"), "qrc:/qml/MockLink.qml");
addSettingsEntry(tr("Debug"), "qrc:/qml/DebugWindow.qml");
addSettingsEntry(tr("Palette Test"),"qrc:/qml/QmlTest.qml");
_addSettingsEntry(tr("Mock Link"), "qrc:/qml/MockLink.qml");
#endif
}
return _customSettingsList;
}
//-----------------------------------------------------------------------------
QGCOptions*
CustomPlugin::options()
QGCOptions* CustomPlugin::options()
{
return _pOptions;
return _options;
}
//-----------------------------------------------------------------------------
QString
CustomPlugin::brandImageIndoor(void) const
QString CustomPlugin::brandImageIndoor(void) const
{
return QStringLiteral("/custom/img/void.png");
return QStringLiteral("/custom/img/CustomAppIcon.png");
}
//-----------------------------------------------------------------------------
QString
CustomPlugin::brandImageOutdoor(void) const
QString CustomPlugin::brandImageOutdoor(void) const
{
return QStringLiteral("/custom/img/void.png");
return QStringLiteral("/custom/img/CustomAppIcon.png");
}
//-----------------------------------------------------------------------------
bool
CustomPlugin::overrideSettingsGroupVisibility(QString name)
bool CustomPlugin::overrideSettingsGroupVisibility(QString name)
{
// We have set up our own specific brand imaging. Hide the brand image settings such that the end user
// can't change it.
if (name == BrandImageSettings::name) {
return false;
}
return true;
}
//-----------------------------------------------------------------------------
VideoManager*
CustomPlugin::createVideoManager(QGCApplication *app, QGCToolbox *toolbox)
{
return new CustomVideoManager(app, toolbox);
}
//-----------------------------------------------------------------------------
VideoReceiver*
CustomPlugin::createVideoReceiver(QObject* parent)
{
return new CustomVideoReceiver(parent);
}
//-----------------------------------------------------------------------------
QQmlApplicationEngine*
CustomPlugin::createRootWindow(QObject *parent)
{
QQmlApplicationEngine* pEngine = new QQmlApplicationEngine(parent);
pEngine->addImportPath("qrc:/qml");
pEngine->addImportPath("qrc:/Custom/Widgets");
pEngine->addImportPath("qrc:/Custom/Camera");
pEngine->rootContext()->setContextProperty("joystickManager", qgcApp()->toolbox()->joystickManager());
pEngine->rootContext()->setContextProperty("debugMessageModel", AppMessages::getModel());
pEngine->load(QUrl(QStringLiteral("qrc:/qml/MainRootWindow.qml")));
return pEngine;
}
//-----------------------------------------------------------------------------
bool
CustomPlugin::adjustSettingMetaData(const QString& settingsGroup, FactMetaData& metaData)
// This allows you to override/hide QGC Application settings
bool CustomPlugin::adjustSettingMetaData(const QString& settingsGroup, FactMetaData& metaData)
{
bool parentResult = QGCCorePlugin::adjustSettingMetaData(settingsGroup, metaData);
if (settingsGroup == AppSettings::settingsGroup) {
if (metaData.name() == AppSettings::appFontPointSizeName) {
#if defined(Q_OS_LINUX)
int defaultFontPointSize = 11;
metaData.setRawDefaultValue(defaultFontPointSize);
#endif
} else if (metaData.name() == AppSettings::indoorPaletteName) {
QVariant indoorPalette = 1;
metaData.setRawDefaultValue(indoorPalette);
parentResult = true;
// This tells QGC than when you are creating Plans while not connected to a vehicle
// the specific firmware/vehicle the plan is for.
if (metaData.name() == AppSettings::offlineEditingFirmwareTypeName) {
metaData.setRawDefaultValue(MAV_AUTOPILOT_PX4);
return false;
} else if (metaData.name() == AppSettings::offlineEditingVehicleTypeName) {
metaData.setRawDefaultValue(MAV_TYPE_QUADROTOR);
return false;
}
}
return parentResult;
}
const QColor CustomPlugin::_windowShadeEnabledLightColor("#FFFFFF");
const QColor CustomPlugin::_windowShadeEnabledDarkColor("#212529");
//-----------------------------------------------------------------------------
void
CustomPlugin::paletteOverride(QString colorName, QGCPalette::PaletteColorInfo_t& colorInfo)
// This modifies QGC colors palette to match possible custom corporate branding
void CustomPlugin::paletteOverride(QString colorName, QGCPalette::PaletteColorInfo_t& colorInfo)
{
if (colorName == QStringLiteral("window")) {
colorInfo[QGCPalette::Dark][QGCPalette::ColorGroupEnabled] = QColor("#212529");
......@@ -430,3 +355,11 @@ CustomPlugin::paletteOverride(QString colorName, QGCPalette::PaletteColorInfo_t&
colorInfo[QGCPalette::Light][QGCPalette::ColorGroupDisabled] = QColor("#48d6ff");
}
}
// We override this so we can get access to QQmlApplicationEngine and use it to register our qml module
QQmlApplicationEngine* CustomPlugin::createQmlApplicationEngine(QObject* parent)
{
QQmlApplicationEngine* qmlEngine = QGCCorePlugin::createQmlApplicationEngine(parent);
qmlEngine->addImportPath("qrc:/Custom/Widgets");
return qmlEngine;
}
......@@ -24,48 +24,21 @@ class CustomSettings;
Q_DECLARE_LOGGING_CATEGORY(CustomLog)
//-- Our own, custom video receiver
class CustomVideoReceiver : public GstVideoReceiver
{
Q_OBJECT
public:
explicit CustomVideoReceiver(QObject* parent = nullptr);
~CustomVideoReceiver();
};
//-----------------------------------------------------------------------------
//-- Our own, custom options
class CustomOptions : public QGCOptions
{
public:
CustomOptions(CustomPlugin*, QObject* parent = nullptr);
bool wifiReliableForCalibration () const final { return true; }
#if defined(Q_OS_LINUX)
double toolbarHeightMultiplier () final { return 1.25; }
#endif
QUrl flyViewOverlay () const final { return QUrl::fromUserInput("qrc:/custom/CustomFlyView.qml"); }
QUrl preFlightChecklistUrl () const final { return QUrl::fromUserInput("qrc:/custom/PreFlightCheckList.qml"); }
//-- We have our own toolbar
QUrl mainToolbarUrl () const final { return QUrl::fromUserInput("qrc:/custom/CustomMainToolBar.qml"); }
QUrl planToolbarUrl () const final { return QUrl::fromUserInput("qrc:/custom/CustomMainToolBar.qml"); }
//-- Don't show instrument widget
CustomInstrumentWidget* instrumentWidget () final { return nullptr; }
bool showMavlinkLogOptions () const final { return false; }
bool showFirmwareUpgrade () const final;
//-- We handle multiple vehicles in a custom way
bool enableMultiVehicleList () const final { return false; }
//-- We handle our own map scale
bool enableMapScale () const final { return false; }
// TODO: Can't access QGCPalette without some workarounds, change this upstream
QColor toolbarBackgroundLight () const final;
QColor toolbarBackgroundDark () const final;
// Overrides from QGCOptions
bool wifiReliableForCalibration (void) const final;
QUrl flyViewOverlay (void) const final;
CustomInstrumentWidget* instrumentWidget (void) final;
bool showFirmwareUpgrade (void) const final;
bool enableMultiVehicleList (void) const final;
};
//-----------------------------------------------------------------------------
class CustomPlugin : public QGCCorePlugin
{
Q_OBJECT
......@@ -74,33 +47,25 @@ public:
~CustomPlugin();
// Overrides from QGCCorePlugin
QVariantList& settingsPages () final;
QGCOptions* options () final;
QString brandImageIndoor () const final;
QString brandImageOutdoor () const final;
QVariantList& settingsPages (void) final;
QGCOptions* options (void) final;
QString brandImageIndoor (void) const final;
QString brandImageOutdoor (void) const final;
bool overrideSettingsGroupVisibility (QString name) final;
VideoManager* createVideoManager (QGCApplication* app, QGCToolbox* toolbox) final;
VideoReceiver* createVideoReceiver (QObject* parent) final;
QQmlApplicationEngine* createRootWindow (QObject* parent) final;
bool adjustSettingMetaData (const QString& settingsGroup, FactMetaData& metaData) final;
void paletteOverride (QString colorName, QGCPalette::PaletteColorInfo_t& colorInfo) final;
QQmlApplicationEngine* createQmlApplicationEngine (QObject* parent) final;
// Overrides from QGCTool
void setToolbox (QGCToolbox* toolbox);
const static QColor _windowShadeEnabledLightColor;
const static QColor _windowShadeEnabledDarkColor;
private slots:
void _advancedChanged (bool advanced);
void _advancedChanged(bool advanced);
private:
void
addSettingsEntry(
const QString& title,
const char* qmlFile,
const char* iconFile = nullptr);
void _addSettingsEntry(const QString& title, const char* qmlFile, const char* iconFile = nullptr);
private:
CustomOptions* _pOptions = nullptr;
QVariantList _customSettingsList; // Not to be mixed up with QGCCorePlugin implementation
CustomOptions* _options = nullptr;
QVariantList _customSettingsList; // Not to be mixed up with QGCCorePlugin implementation
};
/****************************************************************************
*
* (c) 2009-2019 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.
*
* @file
* @brief Custom QtQuick Interface
* @author Gus Grubba <gus@auterion.com>
*/
#include "QGCApplication.h"
#include "AppSettings.h"
#include "SettingsManager.h"
#include "MAVLinkLogManager.h"
#include "QGCMapEngine.h"
#include "QGCApplication.h"
#include "PositionManager.h"
#include "CustomPlugin.h"
#include "CustomQuickInterface.h"
#include <QSettings>
static const char* kGroupName = "CustomSettings";
static const char* kShowGimbalCtl = "ShowGimbalCtl";
static const char* kShowAttitudeWidget = "ShowAttitudeWidget";
//-----------------------------------------------------------------------------
CustomQuickInterface::CustomQuickInterface(QObject* parent)
: QObject(parent)
{
qCDebug(CustomLog) << "CustomQuickInterface Created";
}
//-----------------------------------------------------------------------------
CustomQuickInterface::~CustomQuickInterface()
{
qCDebug(CustomLog) << "CustomQuickInterface Destroyed";
}
//-----------------------------------------------------------------------------
void
CustomQuickInterface::init()
{
QSettings settings;
settings.beginGroup(kGroupName);
_showGimbalControl = settings.value(kShowGimbalCtl, false).toBool();
_showAttitudeWidget = settings.value(kShowAttitudeWidget, false).toBool();
}
//-----------------------------------------------------------------------------
void
CustomQuickInterface::setShowGimbalControl(bool set)
{
if(_showGimbalControl != set) {
_showGimbalControl = set;
QSettings settings;
settings.beginGroup(kGroupName);
settings.setValue(kShowGimbalCtl,set);
emit showGimbalControlChanged();
}
}
//-----------------------------------------------------------------------------
void
CustomQuickInterface::setShowAttitudeWidget(bool set)
{
if(_showAttitudeWidget != set) {
_showAttitudeWidget = set;
QSettings settings;
settings.beginGroup(kGroupName);
settings.setValue(kShowAttitudeWidget,set);
emit showAttitudeWidgetChanged();
}
}
/****************************************************************************
*
* (c) 2009-2019 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.
*
* @file
* @brief Custom QtQuick Interface
* @author Gus Grubba <gus@auterion.com>
*/
#pragma once
#include "Vehicle.h"
#include <QObject>
#include <QTimer>
#include <QColor>
#include <QGeoPositionInfo>
#include <QGeoPositionInfoSource>
//-----------------------------------------------------------------------------
// QtQuick Interface (UI)
class CustomQuickInterface : public QObject
{
Q_OBJECT
public:
CustomQuickInterface(QObject* parent = nullptr);
~CustomQuickInterface();
Q_PROPERTY(bool showGimbalControl READ showGimbalControl WRITE setShowGimbalControl NOTIFY showGimbalControlChanged)
Q_PROPERTY(bool showAttitudeWidget READ showAttitudeWidget WRITE setShowAttitudeWidget NOTIFY showAttitudeWidgetChanged)
bool showGimbalControl () { return _showGimbalControl; }
void setShowGimbalControl (bool set);
void init ();
bool showAttitudeWidget () { return _showAttitudeWidget; }
void setShowAttitudeWidget (bool set);
signals:
void showGimbalControlChanged ();
void showAttitudeWidgetChanged();
private:
bool _showGimbalControl = true;
bool _showAttitudeWidget = false;
};
/****************************************************************************
*
* (c) 2009-2019 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.
*
****************************************************************************/
#include "CustomVideoManager.h"
#include "MultiVehicleManager.h"
#include "CustomCameraManager.h"
#include "CustomCameraControl.h"
//-----------------------------------------------------------------------------
CustomVideoManager::CustomVideoManager(QGCApplication* app, QGCToolbox* toolbox)
: VideoManager(app, toolbox)
{
}
//-----------------------------------------------------------------------------
void
CustomVideoManager::_updateSettings(unsigned id)
{
if(!_videoSettings || !_videoReceiver)
return;
VideoManager::_updateSettings(id);
}
/****************************************************************************
*
* (c) 2009-2019 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.
*
****************************************************************************/
#pragma once
#include <QObject>
#include <QTimer>
#include <QTime>
#include <QUrl>
#include "VideoManager.h"
class CustomVideoManager : public VideoManager
{
Q_OBJECT
public:
CustomVideoManager (QGCApplication* app, QGCToolbox* toolbox);
protected:
void _updateSettings (unsigned id);
};
/****************************************************************************
*
* (c) 2009-2019 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.
*
* @file
* @brief Camera Controller
* @author Gus Grubba <gus@auterion.com>
*
*/
#include "CustomCameraControl.h"
#include "QGCCameraIO.h"
QGC_LOGGING_CATEGORY(CustomCameraLog, "CustomCameraLog")
QGC_LOGGING_CATEGORY(CustomCameraVerboseLog, "CustomCameraVerboseLog")
static const char* kCAM_IRPALETTE = "CAM_IRPALETTE";
static const char* kCAM_NEXTVISION_IRPALETTE = "IR_SENS_POL";
//-----------------------------------------------------------------------------
CustomCameraControl::CustomCameraControl(const mavlink_camera_information_t *info, Vehicle* vehicle, int compID, QObject* parent)
: QGCCameraControl(info, vehicle, compID, parent)
{
}
//-----------------------------------------------------------------------------
bool
CustomCameraControl::takePhoto()
{
bool res = false;
res = QGCCameraControl::takePhoto();
return res;
}
//-----------------------------------------------------------------------------
bool
CustomCameraControl::stopTakePhoto()
{
bool res = QGCCameraControl::stopTakePhoto();
return res;
}
//-----------------------------------------------------------------------------
bool
CustomCameraControl::startVideo()
{
bool res = QGCCameraControl::startVideo();
return res;
}
//-----------------------------------------------------------------------------
bool
CustomCameraControl::stopVideo()
{
bool res = QGCCameraControl::stopVideo();
return res;
}
//-----------------------------------------------------------------------------
void
CustomCameraControl::setVideoMode()
{
if(cameraMode() != CAM_MODE_VIDEO) {
qCDebug(CustomCameraLog) << "setVideoMode()";
Fact* pFact = getFact(kCAM_MODE);
if(pFact) {
pFact->setRawValue(CAM_MODE_VIDEO);
_setCameraMode(CAM_MODE_VIDEO);
}
}
}
//-----------------------------------------------------------------------------
void
CustomCameraControl::setPhotoMode()
{
if(cameraMode() != CAM_MODE_PHOTO) {
qCDebug(CustomCameraLog) << "setPhotoMode()";
Fact* pFact = getFact(kCAM_MODE);
if(pFact) {
pFact->setRawValue(CAM_MODE_PHOTO);
_setCameraMode(CAM_MODE_PHOTO);
}
}
}
//-----------------------------------------------------------------------------
void
CustomCameraControl::_setVideoStatus(VideoStatus status)
{
QGCCameraControl::_setVideoStatus(status);
}
//-----------------------------------------------------------------------------
void
CustomCameraControl::handleCaptureStatus(const mavlink_camera_capture_status_t& cap)
{
QGCCameraControl::handleCaptureStatus(cap);
}
//-----------------------------------------------------------------------------
Fact*
CustomCameraControl::irPalette()
{
if(_paramComplete) {
if(_activeSettings.contains(kCAM_IRPALETTE)) {
return getFact(kCAM_IRPALETTE);
}
else if(_activeSettings.contains(kCAM_NEXTVISION_IRPALETTE)) {
return getFact(kCAM_NEXTVISION_IRPALETTE);
}
}
return nullptr;
}
//-----------------------------------------------------------------------------
void
CustomCameraControl::setThermalMode(ThermalViewMode mode)
{
if(_paramComplete) {
if(vendor() == "NextVision" && _activeSettings.contains("CAM_SENSOR")) {
if(mode == THERMAL_FULL) {
getFact("CAM_SENSOR")->setRawValue(1);
}
else if(mode == THERMAL_OFF) {
getFact("CAM_SENSOR")->setRawValue(0);
}
}
}
QGCCameraControl::setThermalMode(mode);
}
/****************************************************************************
*
* (c) 2009-2019 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.
*
* @file
* @brief Camera Controller
* @author Gus Grubba <gus@auterion.com>
*
*/
#pragma once
#include "QGCCameraControl.h"
#include <QSize>
#include <QPoint>
Q_DECLARE_LOGGING_CATEGORY(CustomCameraLog)
Q_DECLARE_LOGGING_CATEGORY(CustomCameraVerboseLog)
//-----------------------------------------------------------------------------
class CustomCameraControl : public QGCCameraControl
{
Q_OBJECT
public:
CustomCameraControl(const mavlink_camera_information_t* info, Vehicle* vehicle, int compID, QObject* parent = nullptr);
Q_PROPERTY(Fact* irPalette READ irPalette NOTIFY parametersReady)
Fact* irPalette ();
bool takePhoto () override;
bool stopTakePhoto () override;
bool startVideo () override;
bool stopVideo () override;
void setVideoMode () override;
void setPhotoMode () override;
void handleCaptureStatus (const mavlink_camera_capture_status_t& capStatus) override;
void setThermalMode (ThermalViewMode mode) override;
protected:
void _setVideoStatus (VideoStatus status) override;
};
/****************************************************************************
*
* (c) 2009-2019 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.
*
* @file
* @brief Camera Controller
* @author Gus Grubba <gus@auterion.com>
*
*/
#include "QGCApplication.h"
#include "CustomCameraManager.h"
//-----------------------------------------------------------------------------
CustomCameraManager::CustomCameraManager(Vehicle *vehicle)
: QGCCameraManager(vehicle)
{
}
/****************************************************************************
*
* (c) 2009-2019 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.
*
* @file
* @brief Camera Controller
* @author Gus Grubba <gus@auterion.com>
*
*/
#pragma once
#include "QGCCameraManager.h"
//-----------------------------------------------------------------------------
class CustomCameraManager : public QGCCameraManager
{
Q_OBJECT
public:
CustomCameraManager(Vehicle* vehicle);
};
......@@ -13,17 +13,15 @@
#include "CustomFirmwarePlugin.h"
#include "CustomAutoPilotPlugin.h"
#include "CustomCameraManager.h"
#include "CustomCameraControl.h"
//-----------------------------------------------------------------------------
CustomFirmwarePlugin::CustomFirmwarePlugin()
{
for (int i = 0; i < _flightModeInfoList.count(); i++) {
FlightModeInfo_t& info = _flightModeInfoList[i];
//-- Narrow the options to only these two
if (info.name != _altCtlFlightMode &&
info.name != _posCtlFlightMode) {
//-- Narrow the flight mode options to only these
if (info.name != _holdFlightMode && info.name != _rtlFlightMode && info.name != _missionFlightMode) {
// No other flight modes can be set
info.canBeSet = false;
}
}
......@@ -35,34 +33,23 @@ AutoPilotPlugin* CustomFirmwarePlugin::autopilotPlugin(Vehicle* vehicle)
return new CustomAutoPilotPlugin(vehicle, vehicle);
}
//-----------------------------------------------------------------------------
QGCCameraManager*
CustomFirmwarePlugin::createCameraManager(Vehicle *vehicle)
{
return new CustomCameraManager(vehicle);
}
//-----------------------------------------------------------------------------
QGCCameraControl*
CustomFirmwarePlugin::createCameraControl(const mavlink_camera_information_t* info, Vehicle *vehicle, int compID, QObject* parent)
const QVariantList& CustomFirmwarePlugin::toolBarIndicators(const Vehicle* vehicle)
{
return new CustomCameraControl(info, vehicle, compID, parent);
}
//-----------------------------------------------------------------------------
const QVariantList&
CustomFirmwarePlugin::toolBarIndicators(const Vehicle* vehicle)
{
Q_UNUSED(vehicle);
if(_toolBarIndicatorList.size() == 0) {
#if defined(QGC_ENABLE_PAIRING)
_toolBarIndicatorList.append(QVariant::fromValue(QUrl::fromUserInput("qrc:/custom/PairingIndicator.qml")));
#endif
_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/RCRSSIIndicator.qml")));
_toolBarIndicatorList.append(QVariant::fromValue(QUrl::fromUserInput("qrc:/toolbar/BatteryIndicator.qml")));
if (_toolBarIndicatorList.size() == 0) {
// First call the base class to get the standard QGC list. This way we are guaranteed to always get
// any new toolbar indicators which are added upstream in our custom build.
_toolBarIndicatorList = FirmwarePlugin::toolBarIndicators(vehicle);
// Then specifically remove the RC RSSI indicator.
_toolBarIndicatorList.removeOne(QVariant::fromValue(QUrl::fromUserInput("qrc:/toolbar/RCRSSIIndicator.qml")));
}
return _toolBarIndicatorList;
}
// Tells QGC that your vehicle has a gimbal on it. This will in turn cause thing like gimbal commands to point
// the camera straight down for surveys to be automatically added to Plans.
bool CustomFirmwarePlugin::hasGimbal(Vehicle* /*vehicle*/, bool& rollSupported, bool& pitchSupported, bool& yawSupported)
{
rollSupported = false;
pitchSupported = true;
yawSupported = true;
}
......@@ -23,11 +23,12 @@ class CustomFirmwarePlugin : public PX4FirmwarePlugin
Q_OBJECT
public:
CustomFirmwarePlugin();
// FirmwarePlugin overrides
AutoPilotPlugin* autopilotPlugin (Vehicle* vehicle) override;
QGCCameraManager* createCameraManager (Vehicle *vehicle) override;
QGCCameraControl* createCameraControl (const mavlink_camera_information_t* info, Vehicle* vehicle, int compID, QObject* parent = nullptr) override;
const QVariantList& toolBarIndicators (const Vehicle* vehicle) override;
AutoPilotPlugin* autopilotPlugin (Vehicle* vehicle) final;
const QVariantList& toolBarIndicators (const Vehicle* vehicle) final;
bool hasGimbal (Vehicle* vehicle, bool& rollSupported, bool& pitchSupported, bool& yawSupported) final;
private:
QVariantList _toolBarIndicatorList;
};
......@@ -19,6 +19,7 @@ CustomFirmwarePluginFactory CustomFirmwarePluginFactoryImp;
CustomFirmwarePluginFactory::CustomFirmwarePluginFactory()
: _pluginInstance(nullptr)
{
}
QList<MAV_AUTOPILOT> CustomFirmwarePluginFactory::supportedFirmwareTypes() const
......@@ -28,9 +29,8 @@ QList<MAV_AUTOPILOT> CustomFirmwarePluginFactory::supportedFirmwareTypes() const
return list;
}
FirmwarePlugin* CustomFirmwarePluginFactory::firmwarePluginForAutopilot(MAV_AUTOPILOT autopilotType, MAV_TYPE vehicleType)
FirmwarePlugin* CustomFirmwarePluginFactory::firmwarePluginForAutopilot(MAV_AUTOPILOT autopilotType, MAV_TYPE /*vehicleType*/)
{
Q_UNUSED(vehicleType);
if (autopilotType == MAV_AUTOPILOT_PX4) {
if (!_pluginInstance) {
_pluginInstance = new CustomFirmwarePlugin;
......@@ -39,3 +39,11 @@ FirmwarePlugin* CustomFirmwarePluginFactory::firmwarePluginForAutopilot(MAV_AUTO
}
return nullptr;
}
QList<MAV_TYPE> CustomFirmwarePluginFactory::supportedVehicleTypes(void) const
{
QList<MAV_TYPE> mavTypes;
mavTypes.append(MAV_TYPE_QUADROTOR);
return mavTypes;
}
......@@ -17,13 +17,19 @@
class CustomFirmwarePlugin;
/// This custom implementation of FirmwarePluginFactory creates a custom build which only supports
/// PX4 Pro firmware running on a multi-rotor vehicle. This is turn removes portions of the QGC UI
/// related to other firmware and vehicle types. This creating a more simplified UI for a specific
/// type of vehicle.
class CustomFirmwarePluginFactory : public FirmwarePluginFactory
{
Q_OBJECT
public:
CustomFirmwarePluginFactory();
QList<MAV_AUTOPILOT> supportedFirmwareTypes () const override;
FirmwarePlugin* firmwarePluginForAutopilot (MAV_AUTOPILOT autopilotType, MAV_TYPE vehicleType) override;
QList<MAV_AUTOPILOT> supportedFirmwareTypes () const final;
FirmwarePlugin* firmwarePluginForAutopilot (MAV_AUTOPILOT autopilotType, MAV_TYPE vehicleType) final;
QList<MAV_TYPE> supportedVehicleTypes (void) const final;
private:
CustomFirmwarePlugin* _pluginInstance;
};
......
#!/usr/bin/env python
import os
qgc_rc = "qgroundcontrol.qrc"
res_rc = "qgcresources.qrc"
qgc_exc = "qgroundcontrol.exclusion"
res_exc = "qgcresources.exclusion"
def read_file(filename):
with open(filename) as src:
return [line.rstrip().lstrip() for line in src.readlines()]
def process(src, exclusion, dst):
file1 = read_file(src)
file2 = read_file(exclusion)
file3 = open(dst, 'w')
for line in file1:
if line not in file2:
if line.startswith('<qresource') or line.startswith('</qresource'):
file3.write('\t')
if line.startswith('<file') or line.startswith('</file'):
file3.write('\t\t')
newLine = str(line)
if line.startswith('<file'):
newLine = newLine.replace(">", ">../", 1)
file3.write(newLine + '\n')
else:
print 'Excluded:', line
file3.close()
def main():
if(os.path.isfile(qgc_exc)):
process(os.path.join("../",qgc_rc), qgc_exc, qgc_rc)
if(os.path.isfile(res_exc)):
process(os.path.join("../",res_rc), res_exc, res_rc)
if __name__ == '__main__':
main()
......@@ -584,7 +584,8 @@ bool QGCApplication::_initForNormalAppBoot()
QSettings settings;
_qmlAppEngine = toolbox()->corePlugin()->createRootWindow(this);
_qmlAppEngine = toolbox()->corePlugin()->createQmlApplicationEngine(this);
toolbox()->corePlugin()->createRootWindow(_qmlAppEngine);
// Image provider for PX4 Flow
QQuickImageProvider* pImgProvider = dynamic_cast<QQuickImageProvider*>(qgcApp()->toolbox()->imageProvider());
......
......@@ -435,14 +435,18 @@ void QGCCorePlugin::instrumentValueAreaCreateDefaultSettings(const QString& defa
}
}
QQmlApplicationEngine* QGCCorePlugin::createRootWindow(QObject *parent)
{
QQmlApplicationEngine* pEngine = new QQmlApplicationEngine(parent);
pEngine->addImportPath("qrc:/qml");
pEngine->rootContext()->setContextProperty("joystickManager", qgcApp()->toolbox()->joystickManager());
pEngine->rootContext()->setContextProperty("debugMessageModel", AppMessages::getModel());
pEngine->load(QUrl(QStringLiteral("qrc:/qml/MainRootWindow.qml")));
return pEngine;
QQmlApplicationEngine* QGCCorePlugin::createQmlApplicationEngine(QObject* parent)
{
QQmlApplicationEngine* qmlEngine = new QQmlApplicationEngine(parent);
qmlEngine->addImportPath("qrc:/qml");
qmlEngine->rootContext()->setContextProperty("joystickManager", qgcApp()->toolbox()->joystickManager());
qmlEngine->rootContext()->setContextProperty("debugMessageModel", AppMessages::getModel());
return qmlEngine;
}
void QGCCorePlugin::createRootWindow(QQmlApplicationEngine* qmlEngine)
{
qmlEngine->load(QUrl(QStringLiteral("qrc:/qml/MainRootWindow.qml")));
}
bool QGCCorePlugin::mavlinkMessage(Vehicle* vehicle, LinkInterface* link, mavlink_message_t message)
......
......@@ -110,8 +110,12 @@ public:
virtual void instrumentValueAreaCreateDefaultSettings(const QString& defaultSettingsGroup);
/// Allows the plugin to override or get access to the QmlApplicationEngine to do things like add import
/// path or stuff things into the context prior to window creation.
virtual QQmlApplicationEngine* createQmlApplicationEngine(QObject* parent);
/// Allows the plugin to override the creation of the root (native) window.
virtual QQmlApplicationEngine* createRootWindow(QObject* parent);
virtual void createRootWindow(QQmlApplicationEngine* qmlEngine);
/// Allows the plugin to override the creation of VideoManager.
virtual VideoManager* createVideoManager(QGCApplication* app, QGCToolbox* toolbox);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment