Commit df74b9ac authored by Matej Frančeškin's avatar Matej Frančeškin

Merge branch 'master' of https://github.com/mavlink/qgroundcontrol into pr-taisync-android

parents b33d3c56 b9e81086
...@@ -83,7 +83,7 @@ install: ...@@ -83,7 +83,7 @@ install:
# android dependencies: qt, gstreamer, android-ndk # android dependencies: qt, gstreamer, android-ndk
- if [ "${SPEC}" = "android-g++" ]; then - if [ "${SPEC}" = "android-g++" ]; then
wget --quiet http://www.grubba.com/gstreamer-1.0-android-universal-1.14.4.tar.bz2 && wget --quiet https://s3-us-west-2.amazonaws.com/qgroundcontrol/dependencies/gstreamer-1.0-android-universal-1.14.4.tar.bz2 &&
tar jxf gstreamer-1.0-android-universal-1.14.4.tar.bz2 -C ${TRAVIS_BUILD_DIR} && tar jxf gstreamer-1.0-android-universal-1.14.4.tar.bz2 -C ${TRAVIS_BUILD_DIR} &&
wget --quiet https://s3-us-west-2.amazonaws.com/qgroundcontrol/dependencies/Qt5.11.0-android_armv7-min.tar.bz2 && wget --quiet https://s3-us-west-2.amazonaws.com/qgroundcontrol/dependencies/Qt5.11.0-android_armv7-min.tar.bz2 &&
tar jxf Qt5.11.0-android_armv7-min.tar.bz2 -C /tmp && tar jxf Qt5.11.0-android_armv7-min.tar.bz2 -C /tmp &&
......
...@@ -132,6 +132,16 @@ MacBuild { ...@@ -132,6 +132,16 @@ MacBuild {
-lSDL2 -lSDL2
} }
AndroidBuild {
contains(QT_ARCH, arm) {
ANDROID_EXTRA_LIBS += $$BASEDIR/libs/AndroidOpenSSL/arch-armeabi-v7a/lib/libcrypto.so
ANDROID_EXTRA_LIBS += $$BASEDIR/libs/AndroidOpenSSL/arch-armeabi-v7a/lib/libssl.so
} else {
ANDROID_EXTRA_LIBS += $$BASEDIR/libs/AndroidOpenSSL/arch-x86/lib/libcrypto.so
ANDROID_EXTRA_LIBS += $$BASEDIR/libs/AndroidOpenSSL/arch-x86/lib/libssl.so
}
}
# #
# [OPTIONAL] Zeroconf for UDP links # [OPTIONAL] Zeroconf for UDP links
# #
......
...@@ -71,6 +71,8 @@ ...@@ -71,6 +71,8 @@
<uses-feature android:name="android.hardware.location" android:required="false"/> <uses-feature android:name="android.hardware.location" android:required="false"/>
<uses-feature android:name="android.hardware.usb.accessory"/> <uses-feature android:name="android.hardware.usb.accessory"/>
<uses-permission android:name="android.permission.INTERNET" />
<!-- The following comment will be replaced upon deployment with default features based on the dependencies of the application. <!-- The following comment will be replaced upon deployment with default features based on the dependencies of the application.
Remove the comment if you do not require these default features. --> Remove the comment if you do not require these default features. -->
<!-- %%INSERT_FEATURES --> <!-- %%INSERT_FEATURES -->
......
These OpenSLL libraries foir Android are built using the scripts found here: https://github.com/esutton/android-openssl
\ No newline at end of file
Subproject commit c38176a0a63556815ea117c6877ce2dd18739231 Subproject commit 90d9b285e01fe8bfa3b4e8868ca71c5537d43302
...@@ -84,6 +84,7 @@ public: ...@@ -84,6 +84,7 @@ public:
QString flightMode (uint8_t base_mode, uint32_t custom_mode) const override; QString flightMode (uint8_t base_mode, uint32_t custom_mode) const override;
bool setFlightMode (const QString& flightMode, uint8_t* base_mode, uint32_t* custom_mode) override; bool setFlightMode (const QString& flightMode, uint8_t* base_mode, uint32_t* custom_mode) override;
bool isGuidedMode (const Vehicle* vehicle) const override; bool isGuidedMode (const Vehicle* vehicle) const override;
QString gotoFlightMode (void) const override { return QStringLiteral("Guided"); }
QString rtlFlightMode (void) const override { return QString("RTL"); } QString rtlFlightMode (void) const override { return QString("RTL"); }
QString missionFlightMode (void) const override { return QString("Auto"); } QString missionFlightMode (void) const override { return QString("Auto"); }
void pauseVehicle (Vehicle* vehicle) override; void pauseVehicle (Vehicle* vehicle) override;
......
...@@ -757,3 +757,8 @@ int FirmwarePlugin::versionCompare(Vehicle* vehicle, QString& compare) ...@@ -757,3 +757,8 @@ int FirmwarePlugin::versionCompare(Vehicle* vehicle, QString& compare)
int patch = versionNumbers[2].toInt(); int patch = versionNumbers[2].toInt();
return versionCompare(vehicle, major, minor, patch); return versionCompare(vehicle, major, minor, patch);
} }
QString FirmwarePlugin::gotoFlightMode(void) const
{
return QString();
}
...@@ -114,6 +114,9 @@ public: ...@@ -114,6 +114,9 @@ public:
/// Returns whether the vehicle is in guided mode or not. /// Returns whether the vehicle is in guided mode or not.
virtual bool isGuidedMode(const Vehicle* vehicle) const; virtual bool isGuidedMode(const Vehicle* vehicle) const;
/// Returns the flight mode which the vehicle will be in if it is performing a goto location
virtual QString gotoFlightMode(void) const;
/// Set guided flight mode /// Set guided flight mode
virtual void setGuidedMode(Vehicle* vehicle, bool guidedMode); virtual void setGuidedMode(Vehicle* vehicle, bool guidedMode);
......
...@@ -42,6 +42,7 @@ public: ...@@ -42,6 +42,7 @@ public:
QString rtlFlightMode (void) const override { return _rtlFlightMode; } QString rtlFlightMode (void) const override { return _rtlFlightMode; }
QString landFlightMode (void) const override { return _landingFlightMode; } QString landFlightMode (void) const override { return _landingFlightMode; }
QString takeControlFlightMode (void) const override { return _manualFlightMode; } QString takeControlFlightMode (void) const override { return _manualFlightMode; }
QString gotoFlightMode (void) const override { return _holdFlightMode; }
void pauseVehicle (Vehicle* vehicle) override; void pauseVehicle (Vehicle* vehicle) override;
void guidedModeRTL (Vehicle* vehicle) override; void guidedModeRTL (Vehicle* vehicle) override;
void guidedModeLand (Vehicle* vehicle) override; void guidedModeLand (Vehicle* vehicle) override;
......
...@@ -488,13 +488,13 @@ QGCView { ...@@ -488,13 +488,13 @@ QGCView {
exclusiveGroup: multiVehicleSelectorGroup exclusiveGroup: multiVehicleSelectorGroup
text: qsTr("Single") text: qsTr("Single")
checked: true checked: true
color: mapPal.text textColor: mapPal.text
} }
QGCRadioButton { QGCRadioButton {
exclusiveGroup: multiVehicleSelectorGroup exclusiveGroup: multiVehicleSelectorGroup
text: qsTr("Multi-Vehicle") text: qsTr("Multi-Vehicle")
color: mapPal.text textColor: mapPal.text
} }
} }
......
...@@ -295,6 +295,7 @@ FlightMap { ...@@ -295,6 +295,7 @@ FlightMap {
} }
} }
// GoTo Location visuals
MapQuickItem { MapQuickItem {
id: gotoLocationItem id: gotoLocationItem
visible: false visible: false
...@@ -308,6 +309,22 @@ FlightMap { ...@@ -308,6 +309,22 @@ FlightMap {
label: qsTr("Goto here", "Goto here waypoint") label: qsTr("Goto here", "Goto here waypoint")
} }
property bool inGotoFlightMode: _activeVehicle ? _activeVehicle.flightMode === _activeVehicle.gotoFlightMode : false
property var activeVehicle: _activeVehicle
onInGotoFlightModeChanged: {
if (!inGotoFlightMode && visible) {
// Hide goto indicator when vehicle falls out of guided mode
visible = false
}
}
onActiveVehicleChanged: {
if (!_activeVehicle) {
visible = false
}
}
function show(coord) { function show(coord) {
gotoLocationItem.coordinate = coord gotoLocationItem.coordinate = coord
gotoLocationItem.visible = true gotoLocationItem.visible = true
...@@ -316,10 +333,17 @@ FlightMap { ...@@ -316,10 +333,17 @@ FlightMap {
function hide() { function hide() {
gotoLocationItem.visible = false gotoLocationItem.visible = false
} }
}
// Orbit visuals function actionConfirmed() {
// We leave the indicator visible. The handling for onInGuidedModeChanged will hide it.
}
function actionCancelled() {
hide()
}
}
// Orbit editing visuals
QGCMapCircleVisuals { QGCMapCircleVisuals {
id: orbitMapCircle id: orbitMapCircle
mapControl: parent mapControl: parent
...@@ -328,9 +352,16 @@ FlightMap { ...@@ -328,9 +352,16 @@ FlightMap {
property alias center: _mapCircle.center property alias center: _mapCircle.center
property alias clockwiseRotation: _mapCircle.clockwiseRotation property alias clockwiseRotation: _mapCircle.clockwiseRotation
property var activeVehicle: _activeVehicle
readonly property real defaultRadius: 30 readonly property real defaultRadius: 30
onActiveVehicleChanged: {
if (!_activeVehicle) {
visible = false
}
}
function show(coord) { function show(coord) {
_mapCircle.radius.rawValue = defaultRadius _mapCircle.radius.rawValue = defaultRadius
orbitMapCircle.center = coord orbitMapCircle.center = coord
...@@ -341,6 +372,15 @@ FlightMap { ...@@ -341,6 +372,15 @@ FlightMap {
orbitMapCircle.visible = false orbitMapCircle.visible = false
} }
function actionConfirmed() {
// Live orbit status is handled by telemetry so we hide here and telemetry will show again.
hide()
}
function actionCancelled() {
hide()
}
function radius() { function radius() {
return _mapCircle.radius.rawValue return _mapCircle.radius.rawValue
} }
...@@ -357,7 +397,6 @@ FlightMap { ...@@ -357,7 +397,6 @@ FlightMap {
} }
// Orbit telemetry visuals // Orbit telemetry visuals
QGCMapCircleVisuals { QGCMapCircleVisuals {
id: orbitTelemetryCircle id: orbitTelemetryCircle
mapControl: parent mapControl: parent
...@@ -395,7 +434,7 @@ FlightMap { ...@@ -395,7 +434,7 @@ FlightMap {
onTriggered: { onTriggered: {
gotoLocationItem.show(clickMenu.coord) gotoLocationItem.show(clickMenu.coord)
orbitMapCircle.hide() orbitMapCircle.hide()
guidedActionsController.confirmAction(guidedActionsController.actionGoto, clickMenu.coord) guidedActionsController.confirmAction(guidedActionsController.actionGoto, clickMenu.coord, gotoLocationItem)
} }
} }
...@@ -406,7 +445,7 @@ FlightMap { ...@@ -406,7 +445,7 @@ FlightMap {
onTriggered: { onTriggered: {
orbitMapCircle.show(clickMenu.coord) orbitMapCircle.show(clickMenu.coord)
gotoLocationItem.hide() gotoLocationItem.hide()
guidedActionsController.confirmAction(guidedActionsController.actionOrbit, clickMenu.coord) guidedActionsController.confirmAction(guidedActionsController.actionOrbit, clickMenu.coord, orbitMapCircle)
} }
} }
} }
......
...@@ -34,16 +34,14 @@ Rectangle { ...@@ -34,16 +34,14 @@ Rectangle {
property int action property int action
property var actionData property var actionData
property bool hideTrigger: false property bool hideTrigger: false
property var mapIndicator
property real _margins: ScreenTools.defaultFontPixelWidth property real _margins: ScreenTools.defaultFontPixelWidth
property bool _emergencyAction: action === guidedController.actionEmergencyStop property bool _emergencyAction: action === guidedController.actionEmergencyStop
onHideTriggerChanged: { onHideTriggerChanged: {
if (hideTrigger) { if (hideTrigger) {
hideTrigger = false confirmCancelled()
altitudeSlider.visible = false
visibleTimer.stop()
visible = false
} }
} }
...@@ -57,6 +55,17 @@ Rectangle { ...@@ -57,6 +55,17 @@ Rectangle {
} }
} }
function confirmCancelled() {
altitudeSlider.visible = false
visible = false
hideTrigger = false
visibleTimer.stop()
if (mapIndicator) {
mapIndicator.actionCancelled()
mapIndicator = undefined
}
}
Timer { Timer {
id: visibleTimer id: visibleTimer
interval: 1000 interval: 1000
...@@ -107,12 +116,10 @@ Rectangle { ...@@ -107,12 +116,10 @@ Rectangle {
} }
hideTrigger = false hideTrigger = false
guidedController.executeAction(_root.action, _root.actionData, altitudeChange) guidedController.executeAction(_root.action, _root.actionData, altitudeChange)
} if (mapIndicator) {
mapIndicator.actionConfirmed()
onReject: { mapIndicator = undefined
altitudeSlider.visible = false }
_root.visible = false
hideTrigger = false
} }
} }
} }
...@@ -127,12 +134,10 @@ Rectangle { ...@@ -127,12 +134,10 @@ Rectangle {
source: "/res/XDelete.svg" source: "/res/XDelete.svg"
fillMode: Image.PreserveAspectFit fillMode: Image.PreserveAspectFit
color: qgcPal.text color: qgcPal.text
QGCMouseArea { QGCMouseArea {
fillItem: parent fillItem: parent
onClicked: { onClicked: confirmCancelled()
altitudeSlider.visible = false
_root.visible = false
}
} }
} }
} }
...@@ -209,12 +209,13 @@ Item { ...@@ -209,12 +209,13 @@ Item {
} }
// Called when an action is about to be executed in order to confirm // Called when an action is about to be executed in order to confirm
function confirmAction(actionCode, actionData) { function confirmAction(actionCode, actionData, mapIndicator) {
var showImmediate = true var showImmediate = true
closeAll() closeAll()
confirmDialog.action = actionCode confirmDialog.action = actionCode
confirmDialog.actionData = actionData confirmDialog.actionData = actionData
confirmDialog.hideTrigger = true confirmDialog.hideTrigger = true
confirmDialog.mapIndicator = mapIndicator
_actionData = actionData _actionData = actionData
switch (actionCode) { switch (actionCode) {
case actionArm: case actionArm:
...@@ -385,7 +386,6 @@ Item { ...@@ -385,7 +386,6 @@ Item {
break break
case actionOrbit: case actionOrbit:
_activeVehicle.guidedModeOrbit(orbitMapCircle.center, orbitMapCircle.radius() * (orbitMapCircle.clockwiseRotation ? 1 : -1), _activeVehicle.altitudeAMSL.rawValue + actionAltitudeChange) _activeVehicle.guidedModeOrbit(orbitMapCircle.center, orbitMapCircle.radius() * (orbitMapCircle.clockwiseRotation ? 1 : -1), _activeVehicle.altitudeAMSL.rawValue + actionAltitudeChange)
orbitMapCircle.hide()
break break
case actionLandAbort: case actionLandAbort:
_activeVehicle.abortLanding(50) // hardcoded value for climbOutAltitude that is currently ignored _activeVehicle.abortLanding(50) // hardcoded value for climbOutAltitude that is currently ignored
......
...@@ -35,6 +35,7 @@ QGC_LOGGING_CATEGORY(VideoManagerLog, "VideoManagerLog") ...@@ -35,6 +35,7 @@ QGC_LOGGING_CATEGORY(VideoManagerLog, "VideoManagerLog")
VideoManager::VideoManager(QGCApplication* app, QGCToolbox* toolbox) VideoManager::VideoManager(QGCApplication* app, QGCToolbox* toolbox)
: QGCTool(app, toolbox) : QGCTool(app, toolbox)
{ {
_streamInfo = {};
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
...@@ -164,7 +165,8 @@ VideoManager::isGStreamer() ...@@ -164,7 +165,8 @@ VideoManager::isGStreamer()
videoSource == VideoSettings::videoSourceUDP || videoSource == VideoSettings::videoSourceUDP ||
videoSource == VideoSettings::videoSourceRTSP || videoSource == VideoSettings::videoSourceRTSP ||
videoSource == VideoSettings::videoSourceAuto || videoSource == VideoSettings::videoSourceAuto ||
videoSource == VideoSettings::videoSourceTCP; videoSource == VideoSettings::videoSourceTCP ||
videoSource == VideoSettings::videoSourceMPEGTS;
#else #else
return false; return false;
#endif #endif
...@@ -197,14 +199,33 @@ VideoManager::_updateSettings() ...@@ -197,14 +199,33 @@ VideoManager::_updateSettings()
{ {
if(!_videoSettings || !_videoReceiver) if(!_videoSettings || !_videoReceiver)
return; return;
if (_videoSettings->videoSource()->rawValue().toString() == VideoSettings::videoSourceUDP) QString source = _videoSettings->videoSource()->rawValue().toString();
if (source == VideoSettings::videoSourceUDP)
_videoReceiver->setUri(QStringLiteral("udp://0.0.0.0:%1").arg(_videoSettings->udpPort()->rawValue().toInt())); _videoReceiver->setUri(QStringLiteral("udp://0.0.0.0:%1").arg(_videoSettings->udpPort()->rawValue().toInt()));
else if (_videoSettings->videoSource()->rawValue().toString() == VideoSettings::videoSourceRTSP) else if (source == VideoSettings::videoSourceMPEGTS)
_videoReceiver->setUri(QStringLiteral("mpegts://0.0.0.0:%1").arg(_videoSettings->udpPort()->rawValue().toInt()));
else if (source == VideoSettings::videoSourceRTSP)
_videoReceiver->setUri(_videoSettings->rtspUrl()->rawValue().toString()); _videoReceiver->setUri(_videoSettings->rtspUrl()->rawValue().toString());
else if (_videoSettings->videoSource()->rawValue().toString() == VideoSettings::videoSourceTCP) else if (source == VideoSettings::videoSourceTCP)
_videoReceiver->setUri(QStringLiteral("tcp://%1").arg(_videoSettings->tcpUrl()->rawValue().toString())); _videoReceiver->setUri(QStringLiteral("tcp://%1").arg(_videoSettings->tcpUrl()->rawValue().toString()));
else if (isAutoStream()) //-- Auto discovery
_videoReceiver->setUri(QString(_streamInfo.uri)); else if (isAutoStream()) {
switch(_streamInfo.type) {
case VIDEO_STREAM_TYPE_RTSP:
case VIDEO_STREAM_TYPE_TCP_MPEG:
_videoReceiver->setUri(QString(_streamInfo.uri));
break;
case VIDEO_STREAM_TYPE_RTPUDP:
_videoReceiver->setUri(QStringLiteral("udp://0.0.0.0:%1").arg(atoi(_streamInfo.uri)));
break;
case VIDEO_STREAM_TYPE_MPEG_TS_H264:
_videoReceiver->setUri(QStringLiteral("mpegts://0.0.0.0:%1").arg(atoi(_streamInfo.uri)));
break;
default:
_videoReceiver->setUri(QString(_streamInfo.uri));
break;
}
}
} }
//----------------------------------------------------------------------------- //-----------------------------------------------------------------------------
...@@ -212,6 +233,7 @@ void ...@@ -212,6 +233,7 @@ void
VideoManager::_restartVideo() VideoManager::_restartVideo()
{ {
#if defined(QGC_GST_STREAMING) #if defined(QGC_GST_STREAMING)
qCDebug(VideoManagerLog) << "Restart video streaming";
if(!_videoReceiver) if(!_videoReceiver)
return; return;
_videoReceiver->stop(); _videoReceiver->stop();
...@@ -240,7 +262,7 @@ VideoManager::_setActiveVehicle(Vehicle* vehicle) ...@@ -240,7 +262,7 @@ VideoManager::_setActiveVehicle(Vehicle* vehicle)
MAV_CMD_REQUEST_VIDEO_STREAM_INFORMATION, // Command id MAV_CMD_REQUEST_VIDEO_STREAM_INFORMATION, // Command id
false, // ShowError false, // ShowError
1, // First camera only 1, // First camera only
0); // Reserved (Set to 0) 1); // Request video stream information
} }
} }
......
...@@ -61,7 +61,7 @@ public: ...@@ -61,7 +61,7 @@ public:
#endif #endif
void setfullScreen (bool f) { _fullScreen = f; emit fullScreenChanged(); } void setfullScreen (bool f) { _fullScreen = f; emit fullScreenChanged(); }
void setIsTaisync (bool t) { _isTaisync = t; emit isTaisyncChanged(); } void setIsTaisync (bool t) { _isTaisync = t; emit isTaisyncChanged(); }
// Override from QGCTool // Override from QGCTool
void setToolbox (QGCToolbox *toolbox); void setToolbox (QGCToolbox *toolbox);
......
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
"min": 0.1, "min": 0.1,
"units": "m", "units": "m",
"decimalPlaces": 2, "decimalPlaces": 2,
"defaultValue": 10.0 "defaultValue": 50.0
}, },
{ {
"name": "ImageDensity", "name": "ImageDensity",
...@@ -27,7 +27,7 @@ ...@@ -27,7 +27,7 @@
"min": 0, "min": 0,
"units": "cm/px", "units": "cm/px",
"decimalPlaces": 1, "decimalPlaces": 1,
"defaultValue": 25 "defaultValue": 1.2
}, },
{ {
"name": "FrontalOverlap", "name": "FrontalOverlap",
......
...@@ -127,8 +127,8 @@ void CameraCalc::_cameraNameChanged(void) ...@@ -127,8 +127,8 @@ void CameraCalc::_cameraNameChanged(void)
// These values are unknown for these types // These values are unknown for these types
fixedOrientation()->setRawValue(false); fixedOrientation()->setRawValue(false);
minTriggerInterval()->setRawValue(0); minTriggerInterval()->setRawValue(0);
if (isManualCamera()) { if (isManualCamera() && !valueSetIsDistance()->rawValue().toBool()) {
valueSetIsDistance()->setRawValue(false); valueSetIsDistance()->setRawValue(true);
} }
} else { } else {
qWarning() << "Internal Error: Not known camera, but now manual or custom either"; qWarning() << "Internal Error: Not known camera, but now manual or custom either";
......
...@@ -373,7 +373,7 @@ bool FixedWingLandingComplexItem::scanForItem(QmlObjectListModel* visualItems, b ...@@ -373,7 +373,7 @@ bool FixedWingLandingComplexItem::scanForItem(QmlObjectListModel* visualItems, b
MissionItem& missionItemLand = item->missionItem(); MissionItem& missionItemLand = item->missionItem();
if (missionItemLand.command() != MAV_CMD_NAV_LAND || if (missionItemLand.command() != MAV_CMD_NAV_LAND ||
!(missionItemLand.frame() == MAV_FRAME_GLOBAL_RELATIVE_ALT || missionItemLand.frame() == MAV_FRAME_GLOBAL) || !(missionItemLand.frame() == MAV_FRAME_GLOBAL_RELATIVE_ALT || missionItemLand.frame() == MAV_FRAME_GLOBAL) ||
missionItemLand.param1() != 0 || missionItemLand.param2() != 0 || missionItemLand.param3() != 0 || missionItemLand.param4() == 1.0) { missionItemLand.param1() != 0 || missionItemLand.param2() != 0 || missionItemLand.param3() != 0 || missionItemLand.param4() != 0) {
return false; return false;
} }
MAV_FRAME landPointFrame = missionItemLand.frame(); MAV_FRAME landPointFrame = missionItemLand.frame();
...@@ -414,6 +414,7 @@ bool FixedWingLandingComplexItem::scanForItem(QmlObjectListModel* visualItems, b ...@@ -414,6 +414,7 @@ bool FixedWingLandingComplexItem::scanForItem(QmlObjectListModel* visualItems, b
} }
MissionItem& missionItemDoLandStart = item->missionItem(); MissionItem& missionItemDoLandStart = item->missionItem();
if (missionItemDoLandStart.command() != MAV_CMD_DO_LAND_START || if (missionItemDoLandStart.command() != MAV_CMD_DO_LAND_START ||
missionItemDoLandStart.frame() != MAV_FRAME_MISSION ||
missionItemDoLandStart.param1() != 0 || missionItemDoLandStart.param2() != 0 || missionItemDoLandStart.param3() != 0 || missionItemDoLandStart.param4() != 0|| missionItemDoLandStart.param5() != 0|| missionItemDoLandStart.param6() != 0) { missionItemDoLandStart.param1() != 0 || missionItemDoLandStart.param2() != 0 || missionItemDoLandStart.param3() != 0 || missionItemDoLandStart.param4() != 0|| missionItemDoLandStart.param5() != 0|| missionItemDoLandStart.param6() != 0) {
return false; return false;
} }
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include "QGCQGeoCoordinate.h" #include "QGCQGeoCoordinate.h"
#include "PlanMasterController.h" #include "PlanMasterController.h"
#include "KML.h" #include "KML.h"
#include "QGCCorePlugin.h"
#ifndef __mobile__ #ifndef __mobile__
#include "MainWindow.h" #include "MainWindow.h"
...@@ -55,23 +56,24 @@ const char* MissionController::_jsonMavAutopilotKey = "MAV_AUTOPILOT"; ...@@ -55,23 +56,24 @@ const char* MissionController::_jsonMavAutopilotKey = "MAV_AUTOPILOT";
const int MissionController::_missionFileVersion = 2; const int MissionController::_missionFileVersion = 2;
const QString MissionController::patternFWLandingName (tr("Fixed Wing Landing"));
const QString MissionController::patternStructureScanName (tr("Structure Scan"));
const QString MissionController::patternCorridorScanName (tr("Corridor Scan"));
MissionController::MissionController(PlanMasterController* masterController, QObject *parent) MissionController::MissionController(PlanMasterController* masterController, QObject *parent)
: PlanElementController (masterController, parent) : PlanElementController (masterController, parent)
, _missionManager (_managerVehicle->missionManager()) , _missionManager (_managerVehicle->missionManager())
, _missionItemCount (0) , _missionItemCount (0)
, _visualItems (nullptr) , _visualItems (nullptr)
, _settingsItem (nullptr) , _settingsItem (nullptr)
, _firstItemsFromVehicle (false) , _firstItemsFromVehicle (false)
, _itemsRequested (false) , _itemsRequested (false)
, _inRecalcSequence (false) , _inRecalcSequence (false)
, _surveyMissionItemName (tr("Survey")) , _surveyMissionItemName (tr("Survey"))
, _fwLandingMissionItemName (tr("Fixed Wing Landing")) , _appSettings (qgcApp()->toolbox()->settingsManager()->appSettings())
, _structureScanMissionItemName (tr("Structure Scan")) , _progressPct (0)
, _corridorScanMissionItemName (tr("Corridor Scan")) , _currentPlanViewIndex (-1)
, _appSettings (qgcApp()->toolbox()->settingsManager()->appSettings()) , _currentPlanViewItem (nullptr)
, _progressPct (0)
, _currentPlanViewIndex (-1)
, _currentPlanViewItem (nullptr)
{ {
_resetMissionFlightStatus(); _resetMissionFlightStatus();
managerVehicleChanged(_managerVehicle); managerVehicleChanged(_managerVehicle);
...@@ -414,11 +416,11 @@ int MissionController::insertComplexMissionItem(QString itemName, QGeoCoordinate ...@@ -414,11 +416,11 @@ int MissionController::insertComplexMissionItem(QString itemName, QGeoCoordinate
if (itemName == _surveyMissionItemName) { if (itemName == _surveyMissionItemName) {
newItem = new SurveyComplexItem(_controllerVehicle, _flyView, QString() /* kmlFile */, _visualItems /* parent */); newItem = new SurveyComplexItem(_controllerVehicle, _flyView, QString() /* kmlFile */, _visualItems /* parent */);
newItem->setCoordinate(mapCenterCoordinate); newItem->setCoordinate(mapCenterCoordinate);
} else if (itemName == _fwLandingMissionItemName) { } else if (itemName == patternFWLandingName) {
newItem = new FixedWingLandingComplexItem(_controllerVehicle, _flyView, _visualItems /* parent */); newItem = new FixedWingLandingComplexItem(_controllerVehicle, _flyView, _visualItems /* parent */);
} else if (itemName == _structureScanMissionItemName) { } else if (itemName == patternStructureScanName) {
newItem = new StructureScanComplexItem(_controllerVehicle, _flyView, QString() /* kmlFile */, _visualItems /* parent */); newItem = new StructureScanComplexItem(_controllerVehicle, _flyView, QString() /* kmlFile */, _visualItems /* parent */);
} else if (itemName == _corridorScanMissionItemName) { } else if (itemName == patternCorridorScanName) {
newItem = new CorridorScanComplexItem(_controllerVehicle, _flyView, QString() /* kmlFile */, _visualItems /* parent */); newItem = new CorridorScanComplexItem(_controllerVehicle, _flyView, QString() /* kmlFile */, _visualItems /* parent */);
} else { } else {
qWarning() << "Internal error: Unknown complex item:" << itemName; qWarning() << "Internal error: Unknown complex item:" << itemName;
...@@ -434,9 +436,9 @@ int MissionController::insertComplexMissionItemFromKMLOrSHP(QString itemName, QS ...@@ -434,9 +436,9 @@ int MissionController::insertComplexMissionItemFromKMLOrSHP(QString itemName, QS
if (itemName == _surveyMissionItemName) { if (itemName == _surveyMissionItemName) {
newItem = new SurveyComplexItem(_controllerVehicle, _flyView, file, _visualItems); newItem = new SurveyComplexItem(_controllerVehicle, _flyView, file, _visualItems);
} else if (itemName == _structureScanMissionItemName) { } else if (itemName == patternStructureScanName) {
newItem = new StructureScanComplexItem(_controllerVehicle, _flyView, file, _visualItems); newItem = new StructureScanComplexItem(_controllerVehicle, _flyView, file, _visualItems);
} else if (itemName == _corridorScanMissionItemName) { } else if (itemName == patternCorridorScanName) {
newItem = new CorridorScanComplexItem(_controllerVehicle, _flyView, file, _visualItems); newItem = new CorridorScanComplexItem(_controllerVehicle, _flyView, file, _visualItems);
} else { } else {
qWarning() << "Internal error: Unknown complex item:" << itemName; qWarning() << "Internal error: Unknown complex item:" << itemName;
...@@ -1951,15 +1953,15 @@ QStringList MissionController::complexMissionItemNames(void) const ...@@ -1951,15 +1953,15 @@ QStringList MissionController::complexMissionItemNames(void) const
QStringList complexItems; QStringList complexItems;
complexItems.append(_surveyMissionItemName); complexItems.append(_surveyMissionItemName);
complexItems.append(_corridorScanMissionItemName); complexItems.append(patternCorridorScanName);
if (_controllerVehicle->fixedWing()) { if (_controllerVehicle->fixedWing()) {
complexItems.append(_fwLandingMissionItemName); complexItems.append(patternFWLandingName);
} }
if (_controllerVehicle->multiRotor() || _controllerVehicle->vtol()) { if (_controllerVehicle->multiRotor() || _controllerVehicle->vtol()) {
complexItems.append(_structureScanMissionItemName); complexItems.append(patternStructureScanName);
} }
return complexItems; return qgcApp()->toolbox()->corePlugin()->complexMissionItemNames(_controllerVehicle, complexItems);
} }
void MissionController::resumeMission(int resumeIndex) void MissionController::resumeMission(int resumeIndex)
......
...@@ -175,8 +175,8 @@ public: ...@@ -175,8 +175,8 @@ public:
VisualMissionItem* currentPlanViewItem (void) const; VisualMissionItem* currentPlanViewItem (void) const;
double progressPct (void) const { return _progressPct; } double progressPct (void) const { return _progressPct; }
QString surveyComplexItemName (void) const { return _surveyMissionItemName; } QString surveyComplexItemName (void) const { return _surveyMissionItemName; }
QString corridorScanComplexItemName (void) const { return _corridorScanMissionItemName; } QString corridorScanComplexItemName (void) const { return patternCorridorScanName; }
QString structureScanComplexItemName(void) const { return _structureScanMissionItemName; } QString structureScanComplexItemName(void) const { return patternStructureScanName; }
int missionItemCount (void) const { return _missionItemCount; } int missionItemCount (void) const { return _missionItemCount; }
int currentMissionIndex (void) const; int currentMissionIndex (void) const;
...@@ -194,6 +194,12 @@ public: ...@@ -194,6 +194,12 @@ public:
int batteryChangePoint (void) const { return _missionFlightStatus.batteryChangePoint; } ///< -1 for not supported, 0 for not needed int batteryChangePoint (void) const { return _missionFlightStatus.batteryChangePoint; } ///< -1 for not supported, 0 for not needed
int batteriesRequired (void) const { return _missionFlightStatus.batteriesRequired; } ///< -1 for not supported int batteriesRequired (void) const { return _missionFlightStatus.batteriesRequired; } ///< -1 for not supported
// These are the names shown in the UI for the pattern items. They are public so custom builds can remove the ones
// they don't want through the QGCCorePlugin::
static const QString patternFWLandingName;
static const QString patternStructureScanName;
static const QString patternCorridorScanName;
signals: signals:
void visualItemsChanged (void); void visualItemsChanged (void);
void waypointLinesChanged (void); void waypointLinesChanged (void);
...@@ -285,9 +291,6 @@ private: ...@@ -285,9 +291,6 @@ private:
bool _inRecalcSequence; bool _inRecalcSequence;
MissionFlightStatus_t _missionFlightStatus; MissionFlightStatus_t _missionFlightStatus;
QString _surveyMissionItemName; QString _surveyMissionItemName;
QString _fwLandingMissionItemName;
QString _structureScanMissionItemName;
QString _corridorScanMissionItemName;
AppSettings* _appSettings; AppSettings* _appSettings;
double _progressPct; double _progressPct;
int _currentPlanViewIndex; int _currentPlanViewIndex;
......
...@@ -3,7 +3,7 @@ ...@@ -3,7 +3,7 @@
"name": "Radius", "name": "Radius",
"shortDescription": "Radius for geofence circle.", "shortDescription": "Radius for geofence circle.",
"type": "double", "type": "double",
"decimalPlaces": 2, "decimalPlaces": 1,
"min": 0.1, "min": 0.1,
"units": "m" "units": "m"
} }
......
This diff is collapsed.
...@@ -15,7 +15,7 @@ import QGroundControl.Palette 1.0 ...@@ -15,7 +15,7 @@ import QGroundControl.Palette 1.0
/// Mission item edit control /// Mission item edit control
Rectangle { Rectangle {
id: _root id: _root
height: editorLoader.y + (editorLoader.visible ? editorLoader.height : 0) + (_margin * 2) height: editorLoader.visible ? (editorLoader.y + editorLoader.height + (_margin * 2)) : (commandPicker.y + commandPicker.height + _margin / 2)
color: _currentItem ? qgcPal.missionItemEditor : qgcPal.windowShade color: _currentItem ? qgcPal.missionItemEditor : qgcPal.windowShade
radius: _radius radius: _radius
...@@ -90,8 +90,7 @@ Rectangle { ...@@ -90,8 +90,7 @@ Rectangle {
sourceSize.height: _hamburgerSize sourceSize.height: _hamburgerSize
source: "qrc:/qmlimages/Hamburger.svg" source: "qrc:/qmlimages/Hamburger.svg"
visible: missionItem.isCurrentItem && missionItem.sequenceNumber !== 0 visible: missionItem.isCurrentItem && missionItem.sequenceNumber !== 0
color: qgcPal.windowShade color: qgcPal.text
} }
QGCMouseArea { QGCMouseArea {
......
...@@ -760,14 +760,6 @@ QGCView { ...@@ -760,14 +760,6 @@ QGCView {
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: ScreenTools.defaultFontPixelWidth anchors.leftMargin: ScreenTools.defaultFontPixelWidth
readonly property real _buttonRadius: ScreenTools.defaultFontPixelHeight * 0.75 readonly property real _buttonRadius: ScreenTools.defaultFontPixelHeight * 0.75
QGCColoredImage {
width: height
height: ScreenTools.defaultFontPixelWidth * 2.5
sourceSize.height: height
source: "qrc:/res/waypoint.svg"
color: qgcPal.text
anchors.verticalCenter: parent.verticalCenter
}
QGCLabel { QGCLabel {
text: qsTr("Plan") text: qsTr("Plan")
color: qgcPal.text color: qgcPal.text
...@@ -831,7 +823,7 @@ QGCView { ...@@ -831,7 +823,7 @@ QGCView {
QGCListView { QGCListView {
id: missionItemEditorListView id: missionItemEditorListView
anchors.fill: parent anchors.fill: parent
spacing: ScreenTools.defaultFontPixelHeight * 0.5 spacing: ScreenTools.defaultFontPixelHeight / 4
orientation: ListView.Vertical orientation: ListView.Vertical
model: _missionController.visualItems model: _missionController.visualItems
cacheBuffer: Math.max(height * 2, 0) cacheBuffer: Math.max(height * 2, 0)
...@@ -865,9 +857,9 @@ QGCView { ...@@ -865,9 +857,9 @@ QGCView {
GeoFenceEditor { GeoFenceEditor {
anchors.top: rightControls.bottom anchors.top: rightControls.bottom
anchors.topMargin: ScreenTools.defaultFontPixelHeight * 0.5 anchors.topMargin: ScreenTools.defaultFontPixelHeight * 0.5
anchors.bottom: parent.bottom
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
availableHeight: ScreenTools.availableHeight
myGeoFenceController: _geoFenceController myGeoFenceController: _geoFenceController
flightMap: editorMap flightMap: editorMap
visible: _editingLayer == _layerGeoFence visible: _editingLayer == _layerGeoFence
......
...@@ -50,7 +50,7 @@ Rectangle { ...@@ -50,7 +50,7 @@ Rectangle {
color: _outerTextColor color: _outerTextColor
} }
Image { QGCColoredImage {
id: hamburger id: hamburger
anchors.rightMargin: _margin anchors.rightMargin: _margin
anchors.right: parent.right anchors.right: parent.right
...@@ -59,6 +59,7 @@ Rectangle { ...@@ -59,6 +59,7 @@ Rectangle {
height: width height: width
sourceSize.height: height sourceSize.height: height
source: "qrc:/qmlimages/Hamburger.svg" source: "qrc:/qmlimages/Hamburger.svg"
color: qgcPal.text
MouseArea { MouseArea {
anchors.fill: parent anchors.fill: parent
......
...@@ -18,23 +18,46 @@ Rectangle { ...@@ -18,23 +18,46 @@ Rectangle {
color: qgcPal.windowShadeDark color: qgcPal.windowShadeDark
radius: _radius radius: _radius
property bool _specifiesAltitude: missionItem.specifiesAltitude
property real _margin: ScreenTools.defaultFontPixelHeight / 2
property bool _supportsTerrainFrame: missionItem
readonly property int _altModeRelative: 0 readonly property int _altModeRelative: 0
readonly property int _altModeAbsolute: 1 readonly property int _altModeAbsolute: 1
readonly property int _altModeAboveTerrain: 2 readonly property int _altModeAboveTerrain: 2
readonly property int _altModeTerrainFrame: 3 readonly property int _altModeTerrainFrame: 3
ExclusiveGroup { property bool _specifiesAltitude: missionItem.specifiesAltitude
id: altRadios property real _margin: ScreenTools.defaultFontPixelHeight / 2
onCurrentChanged: { property bool _supportsTerrainFrame: missionItem
altModeLabel.text = Qt.binding(function() { return current.helpText })
missionItem.altitudeMode = current.altModeValue property string _altModeRelativeHelpText: qsTr("Altitude relative to home altitude")
property string _altModeAbsoluteHelpText: qsTr("Altitude above mean sea level")
property string _altModeAboveTerrainHelpText: qsTr("Altitude above terrain\nActual AMSL altitude: %1 %2").arg(missionItem.amslAltAboveTerrain.valueString).arg(missionItem.amslAltAboveTerrain.units)
property string _altModeTerrainFrameHelpText: qsTr("Using terrain reference frame")
function updateAltitudeModeText() {
if (missionItem.altitudeMode === _altModeRelative) {
altModeLabel.text = qsTr("Altitude")
altModeHelp.text = _altModeRelativeHelpText
} else if (missionItem.altitudeMode === _altModeAbsolute) {
altModeLabel.text = qsTr("Above Mean Sea Level")
altModeHelp.text = _altModeAbsoluteHelpText
} else if (missionItem.altitudeMode === _altModeAboveTerrain) {
altModeLabel.text = qsTr("Above Terrain")
altModeHelp.text = Qt.binding(function() { return _altModeAboveTerrainHelpText })
} else if (missionItem.altitudeMode === _altModeTerrainFrame) {
altModeLabel.text = qsTr("Terrain Frame")
altModeHelp.text = _altModeTerrainFrameHelpText
} else {
altModeLabel.text = qsTr("Internal Error")
altModeHelp.text = ""
} }
} }
Component.onCompleted: updateAltitudeModeText()
Connections {
target: missionItem
onAltitudeModeChanged: updateAltitudeModeText()
}
Column { Column {
id: valuesColumn id: valuesColumn
anchors.margins: _margin anchors.margins: _margin
...@@ -97,56 +120,70 @@ Rectangle { ...@@ -97,56 +120,70 @@ Rectangle {
anchors.right: parent.right anchors.right: parent.right
spacing: _margin spacing: _margin
QGCLabel { Item {
font.pointSize: ScreenTools.smallFontPointSize width: altHamburger.x + altHamburger.width
text: qsTr("Altitude") height: altModeLabel.height
}
QGCLabel { id: altModeLabel }
RowLayout {
QGCRadioButton { QGCColoredImage {
text: qsTr("Rel") id: altHamburger
exclusiveGroup: altRadios anchors.leftMargin: ScreenTools.defaultFontPixelWidth / 4
checked: missionItem.altitudeMode === altModeValue anchors.left: altModeLabel.right
anchors.top: altModeLabel.top
readonly property int altModeValue: _altModeRelative width: height
readonly property string helpText: qsTr("Relative to home altitude") height: altModeLabel.height
} sourceSize.height: height
QGCRadioButton { source: "qrc:/qmlimages/Hamburger.svg"
text: qsTr("AMSL") color: qgcPal.text
exclusiveGroup: altRadios
checked: missionItem.altitudeMode === altModeValue
visible: QGroundControl.corePlugin.options.showMissionAbsoluteAltitude || missionItem.altitudeMode === altModeValue
readonly property int altModeValue: _altModeAbsolute
readonly property string helpText: qsTr("Above Mean Sea Level")
} }
QGCRadioButton {
text: qsTr("AGL")
exclusiveGroup: altRadios
checked: missionItem.altitudeMode === altModeValue
readonly property int altModeValue: _altModeAboveTerrain QGCMouseArea {
property string helpText: qsTr("Calculated from terrain data\nAMSL Alt ") + missionItem.amslAltAboveTerrain.valueString + " " + missionItem.amslAltAboveTerrain.units anchors.fill: parent
onClicked: altHamburgerMenu.popup()
} }
QGCRadioButton {
text: qsTr("TerrF") Menu {
exclusiveGroup: altRadios id: altHamburgerMenu
checked: missionItem.altitudeMode === altModeValue
visible: missionItem.altitudeMode === altModeValue MenuItem {
text: qsTr("Altitude Relative To Home")
readonly property int altModeValue: _altModeTerrainFrame checkable: true
readonly property string helpText: qsTr("Using terrain reference frame") checked: missionItem.altitudeMode === _altModeRelative
onTriggered: missionItem.altitudeMode = _altModeRelative
}
MenuItem {
text: qsTr("Altitude Above Mean Sea Level")
checkable: true
checked: missionItem.altitudeMode === _altModeAbsolute
visible: QGroundControl.corePlugin.options.showMissionAbsoluteAltitude
onTriggered: missionItem.altitudeMode = _altModeAbsolute
}
MenuItem {
text: qsTr("Altitude Above Terrain")
checkable: true
checked: missionItem.altitudeMode === _altModeAboveTerrain
onTriggered: missionItem.altitudeMode = _altModeAboveTerrain
}
MenuItem {
text: qsTr("Terrain Frame")
checkable: true
checked: missionItem.altitudeMode === _altModeTerrainFrame
visible: missionItem.altitudeMode === _altModeTerrainFrame
onTriggered: missionItem.altitudeMode = _altModeTerrainFrame
}
} }
} }
FactValueSlider { FactTextField {
fact: missionItem.altitude fact: missionItem.altitude
digitCount: 3
incrementSlots: 1
} }
QGCLabel { QGCLabel {
id: altModeLabel id: altModeHelp
anchors.left: parent.left anchors.left: parent.left
anchors.right: parent.right anchors.right: parent.right
wrapMode: Text.WordWrap wrapMode: Text.WordWrap
......
...@@ -36,7 +36,6 @@ void QGCPositionManager::setToolbox(QGCToolbox *toolbox) ...@@ -36,7 +36,6 @@ void QGCPositionManager::setToolbox(QGCToolbox *toolbox)
if(!_defaultSource) { if(!_defaultSource) {
//-- Otherwise, create a default one //-- Otherwise, create a default one
_defaultSource = QGeoPositionInfoSource::createDefaultSource(this); _defaultSource = QGeoPositionInfoSource::createDefaultSource(this);
qDebug() << _defaultSource;
} }
_simulatedSource = new SimulatedPosition(); _simulatedSource = new SimulatedPosition();
......
...@@ -6,96 +6,50 @@ import QGroundControl.Palette 1.0 ...@@ -6,96 +6,50 @@ import QGroundControl.Palette 1.0
import QGroundControl.ScreenTools 1.0 import QGroundControl.ScreenTools 1.0
CheckBox { CheckBox {
activeFocusOnPress: true property color textColor: _qgcPal.text
property bool textBold: false
property real textFontPointSize: ScreenTools.defaultFontPointSize
property var _qgcPal: QGCPalette { colorGroupEnabled: enabled }
property bool _noText: text === ""
property real _radius: ScreenTools.defaultFontPixelHeight * 0.16
property var __qgcPal: QGCPalette { colorGroupEnabled: enabled } activeFocusOnPress: true
style: CheckBoxStyle { style: CheckBoxStyle {
label: Item { label: Item {
implicitWidth: text.implicitWidth + 2 implicitWidth: _noText ? 0 : text.implicitWidth + ScreenTools.defaultFontPixelWidth * 0.25
implicitHeight: ScreenTools.implicitCheckBoxHeight implicitHeight: _noText ? 0 : Math.max(text.implicitHeight, ScreenTools.checkBoxIndicatorSize)
baselineOffset: text.baselineOffset baselineOffset: text.baselineOffset
Rectangle {
anchors.margins: -1
anchors.leftMargin: -3
anchors.rightMargin: -3
anchors.fill: text
visible: control.activeFocus
height: 6
radius: 3
color: "#224f9fef"
border.color: "#47b"
opacity: 0.6
}
Text { Text {
id: text id: text
text: control.text text: control.text
antialiasing: true font.pointSize: textFontPointSize
font.pointSize: ScreenTools.defaultFontPointSize font.bold: control.textBold
font.family: ScreenTools.normalFontFamily color: control.textColor
color: control.__qgcPal.text anchors.centerIn: parent
anchors.verticalCenter: parent.verticalCenter
} }
} // label }
indicator: Item { indicator: Item {
implicitWidth: ScreenTools.checkBoxIndicatorSize implicitWidth: ScreenTools.checkBoxIndicatorSize
implicitHeight: implicitWidth implicitHeight: implicitWidth
Rectangle { Rectangle {
anchors.fill: parent anchors.fill: parent
anchors.bottomMargin: -1 radius: _radius
color: "#44ffffff" border.color: "black"
radius: baserect.radius opacity: control.checkedState === Qt.PartiallyChecked ? 0.5 : 1
}
Rectangle {
Rectangle { anchors.margins: parent.height / 4
id: baserect anchors.fill: parent
property var enabledGradient: Gradient { radius: _radius
GradientStop {color: "#eee" ; position: 0} color: "black"
GradientStop {color: control.pressed ? "#eee" : "#fff" ; position: 0.1} visible: control.checkedState === Qt.Checked
GradientStop {color: "#fff" ; position: 1}
}
property var disabledGradient: Gradient {
GradientStop {color: "#999" ; position: 0}
GradientStop {color: __qgcPal.textField ; position: 0.1}
GradientStop {color: __qgcPal.textField ; position: 0.9}
GradientStop {color: "#999" ; position: 1}
}
gradient: control.enabled ? enabledGradient : disabledGradient
radius: ScreenTools.defaultFontPixelHeight * 0.16
anchors.fill: parent
border.color: control.activeFocus ? "#47b" : "#999"
opacity: control.enabled ? 1 : 0.5
}
Image {
source: "/qmlimages/check.png"
opacity: control.checkedState === Qt.Checked ? control.enabled ? 1 : 0.5 : 0
anchors.centerIn: parent
anchors.verticalCenterOffset: 1
Behavior on opacity {NumberAnimation {duration: 80}}
}
Rectangle {
anchors.fill: parent
anchors.margins: Math.round(baserect.radius)
antialiasing: true
gradient: Gradient {
GradientStop {color: control.pressed ? "#555" : "#999" ; position: 0}
GradientStop {color: "#555" ; position: 1}
} }
radius: baserect.radius - 1
anchors.centerIn: parent
anchors.alignWhenCentered: true
border.color: "#222"
Behavior on opacity {NumberAnimation {duration: 80}}
opacity: control.checkedState === Qt.PartiallyChecked ? control.enabled ? 1 : 0.5 : 0
} }
} // indicator }
} // style }
} }
import QtQuick 2.3 import QtQuick 2.11
import QGroundControl 1.0 import QGroundControl 1.0
import QGroundControl.ScreenTools 1.0 import QGroundControl.ScreenTools 1.0
......
...@@ -6,41 +6,30 @@ import QGroundControl.Palette 1.0 ...@@ -6,41 +6,30 @@ import QGroundControl.Palette 1.0
import QGroundControl.ScreenTools 1.0 import QGroundControl.ScreenTools 1.0
RadioButton { RadioButton {
property var color: qgcPal.text ///< Text color property color textColor: _qgcPal.text
property int textStyle: Text.Normal property bool textBold: false
property color textStyleColor: qgcPal.text property real textFontPointSize: ScreenTools.defaultFontPointSize
property bool textBold: false
property var qgcPal: QGCPalette { colorGroupEnabled: enabled } property var _qgcPal: QGCPalette { colorGroupEnabled: enabled }
property bool _noText: text === ""
activeFocusOnPress: true
style: RadioButtonStyle { style: RadioButtonStyle {
spacing: _noText ? 0 : ScreenTools.defaultFontPixelWidth / 2
label: Item { label: Item {
implicitWidth: text.implicitWidth + ScreenTools.defaultFontPixelWidth * 0.25 implicitWidth: _noText ? 0 : text.implicitWidth + ScreenTools.defaultFontPixelWidth * 0.25
implicitHeight: ScreenTools.implicitRadioButtonHeight implicitHeight: _noText ? 0 : Math.max(text.implicitHeight, ScreenTools.radioButtonIndicatorSize)
baselineOffset: text.y + text.baselineOffset baselineOffset: text.y + text.baselineOffset
Rectangle {
anchors.fill: text
anchors.margins: -1
anchors.leftMargin: -3
anchors.rightMargin:-3
visible: control.activeFocus
height: ScreenTools.defaultFontPixelWidth * 0.25
radius: height * 0.5
color: "#224f9fef"
border.color: "#47b"
opacity: 0.6
}
Text { Text {
id: text id: text
text: control.text text: control.text
font.pointSize: ScreenTools.defaultFontPointSize font.pointSize: textFontPointSize
font.family: ScreenTools.normalFontFamily
font.bold: control.textBold font.bold: control.textBold
antialiasing: true color: control.textColor
color: control.color
style: control.textStyle
styleColor: control.textStyleColor
anchors.centerIn: parent anchors.centerIn: parent
} }
} }
...@@ -49,9 +38,9 @@ RadioButton { ...@@ -49,9 +38,9 @@ RadioButton {
width: ScreenTools.radioButtonIndicatorSize width: ScreenTools.radioButtonIndicatorSize
height: width height: width
color: "white" color: "white"
border.color: control.qgcPal.text border.color: "black"
antialiasing: true
radius: height / 2 radius: height / 2
opacity: control.enabled ? 1 : 0.5
Rectangle { Rectangle {
anchors.centerIn: parent anchors.centerIn: parent
...@@ -60,7 +49,7 @@ RadioButton { ...@@ -60,7 +49,7 @@ RadioButton {
antialiasing: true antialiasing: true
radius: height / 2 radius: height / 2
color: "black" color: "black"
opacity: control.checked ? (control.enabled ? 1 : 0.5) : 0 visible: control.checked
} }
} }
} }
......
...@@ -14,7 +14,6 @@ Rectangle { ...@@ -14,7 +14,6 @@ Rectangle {
color: qgcPal.windowShade color: qgcPal.windowShade
signal accept ///< Action confirmed signal accept ///< Action confirmed
signal reject ///< Action rejected
property string confirmText ///< Text for slider property string confirmText ///< Text for slider
property alias fontPointSize: label.font.pointSize ///< Point size for text property alias fontPointSize: label.font.pointSize ///< Point size for text
...@@ -70,12 +69,6 @@ Rectangle { ...@@ -70,12 +69,6 @@ Rectangle {
property bool dragActive: drag.active property bool dragActive: drag.active
property real _dragOffset: 1 property real _dragOffset: 1
//Component.onCompleted: console.log(height, ScreenTools.minTouchPixels)
onPressed: {
mouse.x
}
onDragActiveChanged: { onDragActiveChanged: {
if (!sliderDragArea.drag.active) { if (!sliderDragArea.drag.active) {
if (slider.x > _maxXDrag - _border) { if (slider.x > _maxXDrag - _border) {
......
This diff is collapsed.
...@@ -25,6 +25,7 @@ const char* VideoSettings::videoSourceAuto = "Automatic Video Stream"; ...@@ -25,6 +25,7 @@ const char* VideoSettings::videoSourceAuto = "Automatic Video Stream";
const char* VideoSettings::videoSourceRTSP = "RTSP Video Stream"; const char* VideoSettings::videoSourceRTSP = "RTSP Video Stream";
const char* VideoSettings::videoSourceUDP = "UDP Video Stream"; const char* VideoSettings::videoSourceUDP = "UDP Video Stream";
const char* VideoSettings::videoSourceTCP = "TCP-MPEG2 Video Stream"; const char* VideoSettings::videoSourceTCP = "TCP-MPEG2 Video Stream";
const char* VideoSettings::videoSourceMPEGTS = "MPEG-TS (h.264) Video Stream";
DECLARE_SETTINGGROUP(Video, "Video") DECLARE_SETTINGGROUP(Video, "Video")
{ {
...@@ -40,6 +41,7 @@ DECLARE_SETTINGGROUP(Video, "Video") ...@@ -40,6 +41,7 @@ DECLARE_SETTINGGROUP(Video, "Video")
videoSourceList.append(videoSourceUDP); videoSourceList.append(videoSourceUDP);
#endif #endif
videoSourceList.append(videoSourceTCP); videoSourceList.append(videoSourceTCP);
videoSourceList.append(videoSourceMPEGTS);
#endif #endif
#ifndef QGC_DISABLE_UVC #ifndef QGC_DISABLE_UVC
QList<QCameraInfo> cameras = QCameraInfo::availableCameras(); QList<QCameraInfo> cameras = QCameraInfo::availableCameras();
...@@ -150,6 +152,11 @@ bool VideoSettings::streamConfigured(void) ...@@ -150,6 +152,11 @@ bool VideoSettings::streamConfigured(void)
qCDebug(VideoManagerLog) << "Testing configuration for TCP Stream:" << tcpUrl()->rawValue().toString(); qCDebug(VideoManagerLog) << "Testing configuration for TCP Stream:" << tcpUrl()->rawValue().toString();
return !tcpUrl()->rawValue().toString().isEmpty(); return !tcpUrl()->rawValue().toString().isEmpty();
} }
//-- If MPEG-TS, check if port is set
if(vSource == videoSourceMPEGTS) {
qCDebug(VideoManagerLog) << "Testing configuration for MPEG-TS Stream:" << udpPort()->rawValue().toInt();
return udpPort()->rawValue().toInt() != 0;
}
//-- If Auto, check for received URL //-- If Auto, check for received URL
if(vSource == videoSourceAuto) { if(vSource == videoSourceAuto) {
qCDebug(VideoManagerLog) << "Testing configuration for Auto Stream:" << qgcApp()->toolbox()->videoManager()->autoURL(); qCDebug(VideoManagerLog) << "Testing configuration for Auto Stream:" << qgcApp()->toolbox()->videoManager()->autoURL();
......
...@@ -40,12 +40,14 @@ public: ...@@ -40,12 +40,14 @@ public:
Q_PROPERTY(QString rtspVideoSource READ rtspVideoSource CONSTANT) Q_PROPERTY(QString rtspVideoSource READ rtspVideoSource CONSTANT)
Q_PROPERTY(QString udpVideoSource READ udpVideoSource CONSTANT) Q_PROPERTY(QString udpVideoSource READ udpVideoSource CONSTANT)
Q_PROPERTY(QString tcpVideoSource READ tcpVideoSource CONSTANT) Q_PROPERTY(QString tcpVideoSource READ tcpVideoSource CONSTANT)
Q_PROPERTY(QString mpegtsVideoSource READ mpegtsVideoSource CONSTANT)
bool streamConfigured (); bool streamConfigured ();
QString autoVideoSource () { return videoSourceAuto; } QString autoVideoSource () { return videoSourceAuto; }
QString rtspVideoSource () { return videoSourceRTSP; } QString rtspVideoSource () { return videoSourceRTSP; }
QString udpVideoSource () { return videoSourceUDP; } QString udpVideoSource () { return videoSourceUDP; }
QString tcpVideoSource () { return videoSourceTCP; } QString tcpVideoSource () { return videoSourceTCP; }
QString mpegtsVideoSource () { return videoSourceMPEGTS; }
static const char* videoSourceNoVideo; static const char* videoSourceNoVideo;
static const char* videoDisabled; static const char* videoDisabled;
...@@ -53,6 +55,7 @@ public: ...@@ -53,6 +55,7 @@ public:
static const char* videoSourceRTSP; static const char* videoSourceRTSP;
static const char* videoSourceAuto; static const char* videoSourceAuto;
static const char* videoSourceTCP; static const char* videoSourceTCP;
static const char* videoSourceMPEGTS;
signals: signals:
void streamConfiguredChanged (); void streamConfiguredChanged ();
......
...@@ -2962,6 +2962,11 @@ bool Vehicle::takeoffVehicleSupported() const ...@@ -2962,6 +2962,11 @@ bool Vehicle::takeoffVehicleSupported() const
return _firmwarePlugin->isCapable(this, FirmwarePlugin::TakeoffVehicleCapability); return _firmwarePlugin->isCapable(this, FirmwarePlugin::TakeoffVehicleCapability);
} }
QString Vehicle::gotoFlightMode() const
{
return _firmwarePlugin->gotoFlightMode();
}
void Vehicle::guidedModeRTL(void) void Vehicle::guidedModeRTL(void)
{ {
if (!guidedModeSupported()) { if (!guidedModeSupported()) {
......
...@@ -636,13 +636,14 @@ public: ...@@ -636,13 +636,14 @@ public:
Q_PROPERTY(QGCMapCircle* orbitMapCircle READ orbitMapCircle CONSTANT) Q_PROPERTY(QGCMapCircle* orbitMapCircle READ orbitMapCircle CONSTANT)
// Vehicle state used for guided control // Vehicle state used for guided control
Q_PROPERTY(bool flying READ flying NOTIFY flyingChanged) ///< Vehicle is flying Q_PROPERTY(bool flying READ flying NOTIFY flyingChanged) ///< Vehicle is flying
Q_PROPERTY(bool landing READ landing NOTIFY landingChanged) ///< Vehicle is in landing pattern (DO_LAND_START) Q_PROPERTY(bool landing READ landing NOTIFY landingChanged) ///< Vehicle is in landing pattern (DO_LAND_START)
Q_PROPERTY(bool guidedMode READ guidedMode WRITE setGuidedMode NOTIFY guidedModeChanged) ///< Vehicle is in Guided mode and can respond to guided commands Q_PROPERTY(bool guidedMode READ guidedMode WRITE setGuidedMode NOTIFY guidedModeChanged) ///< Vehicle is in Guided mode and can respond to guided commands
Q_PROPERTY(bool guidedModeSupported READ guidedModeSupported CONSTANT) ///< Guided mode commands are supported by this vehicle Q_PROPERTY(bool guidedModeSupported READ guidedModeSupported CONSTANT) ///< Guided mode commands are supported by this vehicle
Q_PROPERTY(bool pauseVehicleSupported READ pauseVehicleSupported CONSTANT) ///< Pause vehicle command is supported Q_PROPERTY(bool pauseVehicleSupported READ pauseVehicleSupported CONSTANT) ///< Pause vehicle command is supported
Q_PROPERTY(bool orbitModeSupported READ orbitModeSupported CONSTANT) ///< Orbit mode is supported by this vehicle Q_PROPERTY(bool orbitModeSupported READ orbitModeSupported CONSTANT) ///< Orbit mode is supported by this vehicle
Q_PROPERTY(bool takeoffVehicleSupported READ takeoffVehicleSupported CONSTANT) ///< Guided takeoff supported Q_PROPERTY(bool takeoffVehicleSupported READ takeoffVehicleSupported CONSTANT) ///< Guided takeoff supported
Q_PROPERTY(QString gotoFlightMode READ gotoFlightMode CONSTANT) ///< Flight mode vehicle is in while performing goto
Q_PROPERTY(ParameterManager* parameterManager READ parameterManager CONSTANT) Q_PROPERTY(ParameterManager* parameterManager READ parameterManager CONSTANT)
...@@ -761,10 +762,11 @@ public: ...@@ -761,10 +762,11 @@ public:
/// @param percent 0-no power, 100-full power /// @param percent 0-no power, 100-full power
Q_INVOKABLE void motorTest(int motor, int percent); Q_INVOKABLE void motorTest(int motor, int percent);
bool guidedModeSupported (void) const; bool guidedModeSupported (void) const;
bool pauseVehicleSupported (void) const; bool pauseVehicleSupported (void) const;
bool orbitModeSupported (void) const; bool orbitModeSupported (void) const;
bool takeoffVehicleSupported(void) const; bool takeoffVehicleSupported (void) const;
QString gotoFlightMode (void) const;
// Property accessors // Property accessors
......
...@@ -239,9 +239,10 @@ VideoReceiver::start() ...@@ -239,9 +239,10 @@ VideoReceiver::start()
#else #else
bool isTaisyncUSB = false; bool isTaisyncUSB = false;
#endif #endif
bool isUdp = _uri.contains("udp://") && !isTaisyncUSB; bool isUdp = _uri.contains("udp://") && !isTaisyncUSB;
bool isRtsp = _uri.contains("rtsp://") && !isTaisyncUSB; bool isRtsp = _uri.contains("rtsp://") && !isTaisyncUSB;
bool isTCP = _uri.contains("tcp://") && !isTaisyncUSB; bool isTCP = _uri.contains("tcp://") && !isTaisyncUSB;
bool isMPEGTS = _uri.contains("mpegts://") && !isTaisyncUSB;
if (!isTaisyncUSB && _uri.isEmpty()) { if (!isTaisyncUSB && _uri.isEmpty()) {
qCritical() << "VideoReceiver::start() failed because URI is not specified"; qCritical() << "VideoReceiver::start() failed because URI is not specified";
...@@ -281,7 +282,7 @@ VideoReceiver::start() ...@@ -281,7 +282,7 @@ VideoReceiver::start()
break; break;
} }
if(isUdp || isTaisyncUSB) { if(isUdp || isMPEGTS || isTaisyncUSB) {
dataSource = gst_element_factory_make("udpsrc", "udp-source"); dataSource = gst_element_factory_make("udpsrc", "udp-source");
} else if(isTCP) { } else if(isTCP) {
dataSource = gst_element_factory_make("tcpclientsrc", "tcpclient-source"); dataSource = gst_element_factory_make("tcpclientsrc", "tcpclient-source");
...@@ -309,24 +310,26 @@ VideoReceiver::start() ...@@ -309,24 +310,26 @@ VideoReceiver::start()
} else if(isTCP) { } else if(isTCP) {
QUrl url(_uri); QUrl url(_uri);
g_object_set(static_cast<gpointer>(dataSource), "host", qPrintable(url.host()), "port", url.port(), nullptr ); g_object_set(static_cast<gpointer>(dataSource), "host", qPrintable(url.host()), "port", url.port(), nullptr );
} else if(isMPEGTS) {
QUrl url(_uri);
g_object_set(static_cast<gpointer>(dataSource), "port", url.port(), nullptr);
} else { } else {
g_object_set(static_cast<gpointer>(dataSource), "location", qPrintable(_uri), "latency", 17, "udp-reconnect", 1, "timeout", _udpReconnect_us, NULL); g_object_set(static_cast<gpointer>(dataSource), "location", qPrintable(_uri), "latency", 17, "udp-reconnect", 1, "timeout", _udpReconnect_us, NULL);
} }
// Currently, we expect H264 when using anything except for TCP. Long term we may want this to be settable if (isTCP || isMPEGTS) {
if (isTCP) { if ((demux = gst_element_factory_make("tsdemux", "mpeg-ts-demuxer")) == nullptr) {
if ((demux = gst_element_factory_make("tsdemux", "mpeg2-ts-demuxer")) == nullptr) {
qCritical() << "VideoReceiver::start() failed. Error with gst_element_factory_make('tsdemux')"; qCritical() << "VideoReceiver::start() failed. Error with gst_element_factory_make('tsdemux')";
break; break;
} }
} else { } else {
if(!isTaisyncUSB) { if(!isTaisyncUSB) {
if ((demux = gst_element_factory_make("rtph264depay", "rtp-h264-depacketizer")) == nullptr) { if ((demux = gst_element_factory_make("rtph264depay", "rtp-h264-depacketizer")) == nullptr) {
qCritical() << "VideoReceiver::start() failed. Error with gst_element_factory_make('rtph264depay')"; qCritical() << "VideoReceiver::start() failed. Error with gst_element_factory_make('rtph264depay')";
break; break;
}
} }
} }
}
if ((parser = gst_element_factory_make("h264parse", "h264-parser")) == nullptr) { if ((parser = gst_element_factory_make("h264parse", "h264-parser")) == nullptr) {
qCritical() << "VideoReceiver::start() failed. Error with gst_element_factory_make('h264parse')"; qCritical() << "VideoReceiver::start() failed. Error with gst_element_factory_make('h264parse')";
...@@ -374,13 +377,13 @@ VideoReceiver::start() ...@@ -374,13 +377,13 @@ VideoReceiver::start()
qCritical() << "Unable to link Taisync USB elements."; qCritical() << "Unable to link Taisync USB elements.";
break; break;
} }
} else if (isTCP) { } else if (isTCP || isMPEGTS) {
if(!gst_element_link(dataSource, demux)) { if(!gst_element_link(dataSource, demux)) {
qCritical() << "Unable to link TCP dataSource to Demux."; qCritical() << "Unable to link TCP/MPEG-TS dataSource to Demux.";
break; break;
} }
if(!gst_element_link_many(parser, _tee, queue, decoder, queue1, _videoSink, nullptr)) { if(!gst_element_link_many(parser, _tee, queue, decoder, queue1, _videoSink, nullptr)) {
qCritical() << "Unable to link TCP pipline to parser."; qCritical() << "Unable to link TCP/MPEG-TS pipline to parser.";
break; break;
} }
g_signal_connect(demux, "pad-added", G_CALLBACK(newPadCB), parser); g_signal_connect(demux, "pad-added", G_CALLBACK(newPadCB), parser);
...@@ -469,7 +472,7 @@ VideoReceiver::start() ...@@ -469,7 +472,7 @@ VideoReceiver::start()
void void
VideoReceiver::stop() VideoReceiver::stop()
{ {
if(!qgcApp()->runningUnitTests()) { if(qgcApp()->runningUnitTests()) {
return; return;
} }
#if defined(QGC_GST_STREAMING) #if defined(QGC_GST_STREAMING)
......
...@@ -130,11 +130,13 @@ void initializeVideoStreaming(int &argc, char* argv[], char* logpath, char* debu ...@@ -130,11 +130,13 @@ void initializeVideoStreaming(int &argc, char* argv[], char* logpath, char* debu
#else #else
//-- Generic initialization //-- Generic initialization
if (logpath) { if (logpath) {
QString gstDebugFile = QString("%1/%2").arg(logpath).arg("gstreamer-log.txt");
qDebug() << "GStreamer debug output:" << gstDebugFile;
if (debuglevel) { if (debuglevel) {
qputenv("GST_DEBUG", debuglevel); qputenv("GST_DEBUG", debuglevel);
} }
qputenv("GST_DEBUG_NO_COLOR", "1"); qputenv("GST_DEBUG_NO_COLOR", "1");
qputenv("GST_DEBUG_FILE", QString("%1/%2").arg(logpath).arg("gstreamer-log.txt").toUtf8()); qputenv("GST_DEBUG_FILE", gstDebugFile.toUtf8());
qputenv("GST_DEBUG_DUMP_DOT_DIR", logpath); qputenv("GST_DEBUG_DUMP_DOT_DIR", logpath);
} }
GError* error = nullptr; GError* error = nullptr;
......
...@@ -139,6 +139,11 @@ public: ...@@ -139,6 +139,11 @@ public:
/// Custom builds must override to provide their own location. /// Custom builds must override to provide their own location.
virtual QString stableDownloadLocation(void) const { return QString("qgroundcontrol.com"); } virtual QString stableDownloadLocation(void) const { return QString("qgroundcontrol.com"); }
/// Returns the complex mission items to display in the Plan UI
/// @param complexMissionItemNames Default set of complex items
/// @return Complex items to be made available to user
virtual QStringList complexMissionItemNames(Vehicle* vehicle, const QStringList& complexMissionItemNames) { Q_UNUSED(vehicle); return complexMissionItemNames; }
bool showTouchAreas(void) const { return _showTouchAreas; } bool showTouchAreas(void) const { return _showTouchAreas; }
bool showAdvancedUI(void) const { return _showAdvancedUI; } bool showAdvancedUI(void) const { return _showAdvancedUI; }
void setShowTouchAreas(bool show); void setShowTouchAreas(bool show);
......
...@@ -37,7 +37,7 @@ QGCView { ...@@ -37,7 +37,7 @@ QGCView {
property Fact _userBrandImageIndoor: QGroundControl.settingsManager.brandImageSettings.userBrandImageIndoor property Fact _userBrandImageIndoor: QGroundControl.settingsManager.brandImageSettings.userBrandImageIndoor
property Fact _userBrandImageOutdoor: QGroundControl.settingsManager.brandImageSettings.userBrandImageOutdoor property Fact _userBrandImageOutdoor: QGroundControl.settingsManager.brandImageSettings.userBrandImageOutdoor
property real _labelWidth: ScreenTools.defaultFontPixelWidth * 20 property real _labelWidth: ScreenTools.defaultFontPixelWidth * 20
property real _comboFieldWidth: ScreenTools.defaultFontPixelWidth * 25 property real _comboFieldWidth: ScreenTools.defaultFontPixelWidth * 28
property real _valueFieldWidth: ScreenTools.defaultFontPixelWidth * 10 property real _valueFieldWidth: ScreenTools.defaultFontPixelWidth * 10
property Fact _mapProvider: QGroundControl.settingsManager.flightMapSettings.mapProvider property Fact _mapProvider: QGroundControl.settingsManager.flightMapSettings.mapProvider
property Fact _mapType: QGroundControl.settingsManager.flightMapSettings.mapType property Fact _mapType: QGroundControl.settingsManager.flightMapSettings.mapType
...@@ -51,6 +51,7 @@ QGCView { ...@@ -51,6 +51,7 @@ QGCView {
property bool _isUDP: _isGst && _videoSource === QGroundControl.settingsManager.videoSettings.udpVideoSource property bool _isUDP: _isGst && _videoSource === QGroundControl.settingsManager.videoSettings.udpVideoSource
property bool _isRTSP: _isGst && _videoSource === QGroundControl.settingsManager.videoSettings.rtspVideoSource property bool _isRTSP: _isGst && _videoSource === QGroundControl.settingsManager.videoSettings.rtspVideoSource
property bool _isTCP: _isGst && _videoSource === QGroundControl.settingsManager.videoSettings.tcpVideoSource property bool _isTCP: _isGst && _videoSource === QGroundControl.settingsManager.videoSettings.tcpVideoSource
property bool _isMPEGTS: _isGst && _videoSource === QGroundControl.settingsManager.videoSettings.mpegtsVideoSource
readonly property real _internalWidthRatio: 0.8 readonly property real _internalWidthRatio: 0.8
...@@ -707,7 +708,6 @@ QGCView { ...@@ -707,7 +708,6 @@ QGCView {
Layout.fillWidth: false Layout.fillWidth: false
Layout.fillHeight: false Layout.fillHeight: false
columns: 2 columns: 2
QGCLabel { QGCLabel {
text: qsTr("Video Source") text: qsTr("Video Source")
visible: QGroundControl.settingsManager.videoSettings.videoSource.visible visible: QGroundControl.settingsManager.videoSettings.videoSource.visible
...@@ -722,12 +722,12 @@ QGCView { ...@@ -722,12 +722,12 @@ QGCView {
QGCLabel { QGCLabel {
text: qsTr("UDP Port") text: qsTr("UDP Port")
visible: _isUDP && QGroundControl.settingsManager.videoSettings.udpPort.visible visible: (_isUDP || _isMPEGTS) && QGroundControl.settingsManager.videoSettings.udpPort.visible
} }
FactTextField { FactTextField {
Layout.preferredWidth: _comboFieldWidth Layout.preferredWidth: _comboFieldWidth
fact: QGroundControl.settingsManager.videoSettings.udpPort fact: QGroundControl.settingsManager.videoSettings.udpPort
visible: _isUDP && QGroundControl.settingsManager.videoSettings.udpPort.visible visible: (_isUDP || _isMPEGTS) && QGroundControl.settingsManager.videoSettings.udpPort.visible
} }
QGCLabel { QGCLabel {
......
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