Commit a7ddca45 authored by Gus Grubba's avatar Gus Grubba

Merge branch 'master' of https://github.com/mavlink/qgroundcontrol into AirmapUI

parents ff661fa7 5b94043d
......@@ -22,7 +22,6 @@ import QGroundControl.ScreenTools 1.0
SetupPage {
id: safetyPage
pageComponent: safetyPageComponent
visibleWhileArmed: true
Component {
id: safetyPageComponent
......
......@@ -21,8 +21,9 @@ import QGroundControl.Controllers 1.0
/// Base view control for all Setup pages
QGCView {
id: setupView
viewPanel: setupPanel
id: setupView
viewPanel: setupPanel
enabled: !_shouldDisableWhenArmed
property alias pageComponent: pageLoader.sourceComponent
property string pageName: vehicleComponent ? vehicleComponent.name : ""
......@@ -30,53 +31,15 @@ QGCView {
property real availableWidth: width - pageLoader.x
property real availableHeight: height - pageLoader.y
property real _margins: ScreenTools.defaultFontPixelHeight / 2
property bool _vehicleArmed: QGroundControl.multiVehicleManager.activeVehicle ? QGroundControl.multiVehicleManager.activeVehicle.armed : false
property bool _shouldDisableWhenArmed: _vehicleArmed ? (vehicleComponent ? !vehicleComponent.allowSetupWhileArmed : false) : false
property bool visibleWhileArmed: false
property real _margins: ScreenTools.defaultFontPixelHeight * 0.5
property string _pageTitle: qsTr("%1 Setup").arg(pageName)
property bool vehicleArmed: QGroundControl.multiVehicleManager.activeVehicle ? QGroundControl.multiVehicleManager.activeVehicle.armed : false
onVehicleArmedChanged: {
if (visibleWhileArmed) {
return
}
if (vehicleArmed) {
disabledWhileArmed.visible = true
setupView.viewPanel.enabled = false
} else {
disabledWhileArmed.visible = false
setupView.viewPanel.enabled = true
}
}
QGCPalette { id: qgcPal; colorGroupEnabled: setupPanel.enabled }
// Overlay to display when vehicle is armed and the setup page needs
// to be disabled
Item {
id: disabledWhileArmed
visible: false
z: 9999
anchors.fill: parent
Rectangle {
anchors.fill: parent
color: "black"
opacity: 0.5
}
QGCLabel {
anchors.margins: defaultTextWidth * 2
anchors.fill: parent
verticalAlignment: Text.AlignVCenter
horizontalAlignment: Text.AlignHCenter
wrapMode: Text.WordWrap
font.pointSize: ScreenTools.largeFontPointSize
color: "red"
text: "Setup disabled while the vehicle is armed"
}
}
QGCViewPanel {
id: setupPanel
anchors.fill: parent
......@@ -88,13 +51,13 @@ QGCView {
clip: true
Column {
id: headingColumn
width: setupPanel.width
spacing: _margins
id: headingColumn
width: setupPanel.width
spacing: _margins
QGCLabel {
font.pointSize: ScreenTools.largeFontPointSize
text: pageName + " " + qsTr("Setup")
text: _shouldDisableWhenArmed ? _pageTitle + "<font color=\"red\">" + qsTr(" (Disabled while the vehicle is armed)") + "</font>" : _pageTitle
visible: !ScreenTools.isShortScreen
}
......@@ -112,6 +75,14 @@ QGCView {
anchors.topMargin: _margins
anchors.top: headingColumn.bottom
}
// Overlay to display when vehicle is armed and this setup page needs
// to be disabled
Rectangle {
visible: _shouldDisableWhenArmed
anchors.fill: pageLoader
color: "black"
opacity: 0.5
}
}
}
}
......@@ -43,24 +43,24 @@ SetupPage {
readonly property string highlightPrefix: "<font color=\"" + qgcPal.warningText + "\">"
readonly property string highlightSuffix: "</font>"
function getBatteryImage()
{
switch(battNumCells.value) {
case 1: return "/qmlimages/PowerComponentBattery_01cell.svg";
case 2: return "/qmlimages/PowerComponentBattery_02cell.svg"
case 3: return "/qmlimages/PowerComponentBattery_03cell.svg"
case 4: return "/qmlimages/PowerComponentBattery_04cell.svg"
case 5: return "/qmlimages/PowerComponentBattery_05cell.svg"
case 6: return "/qmlimages/PowerComponentBattery_06cell.svg"
default: return "/qmlimages/PowerComponentBattery_01cell.svg";
}
}
ColumnLayout {
id: innerColumn
anchors.horizontalCenter: parent.horizontalCenter
spacing: ScreenTools.defaultFontPixelHeight
function getBatteryImage()
{
switch(battNumCells.value) {
case 1: return "/qmlimages/PowerComponentBattery_01cell.svg";
case 2: return "/qmlimages/PowerComponentBattery_02cell.svg"
case 3: return "/qmlimages/PowerComponentBattery_03cell.svg"
case 4: return "/qmlimages/PowerComponentBattery_04cell.svg"
case 5: return "/qmlimages/PowerComponentBattery_05cell.svg"
case 6: return "/qmlimages/PowerComponentBattery_06cell.svg"
default: return "/qmlimages/PowerComponentBattery_01cell.svg";
}
}
function drawArrowhead(ctx, x, y, radians)
{
ctx.save();
......
......@@ -341,7 +341,7 @@ QGCView {
anchors.left: _panel.left
anchors.bottom: _panel.bottom
anchors.margins: ScreenTools.defaultFontPixelHeight
visible: QGroundControl.videoManager.hasVideo && !QGroundControl.videoManager.fullScreen
visible: QGroundControl.videoManager.hasVideo && !QGroundControl.videoManager.fullScreen && _flightVideo.state != "popup"
isHidden: !_isPipVisible
isDark: isBackgroundDark
enablePopup: _mainIsMap
......
......@@ -21,8 +21,9 @@ public:
CameraCalc(Vehicle* vehicle, QObject* parent = NULL);
Q_PROPERTY(QString cameraName READ cameraName WRITE setCameraName NOTIFY cameraNameChanged)
Q_PROPERTY(QString customCameraName READ customCameraName CONSTANT) // Camera name for custom camera setting
Q_PROPERTY(QString manualCameraName READ manualCameraName CONSTANT) // Camera name for manual camera setting
Q_PROPERTY(QString customCameraName READ customCameraName CONSTANT) ///< Camera name for custom camera setting
Q_PROPERTY(QString manualCameraName READ manualCameraName CONSTANT) ///< Camera name for manual camera setting
Q_PROPERTY(bool isManualCamera READ isManualCamera NOTIFY cameraNameChanged) ///< true: using manual camera
Q_PROPERTY(Fact* valueSetIsDistance READ valueSetIsDistance CONSTANT) ///< true: distance specified, resolution calculated
Q_PROPERTY(Fact* distanceToSurface READ distanceToSurface CONSTANT) ///< Distance to surface for image foot print calculation
Q_PROPERTY(Fact* imageDensity READ imageDensity CONSTANT) ///< Image density on surface (cm/px)
......@@ -48,8 +49,9 @@ public:
Fact* adjustedFootprintSide (void) { return &_adjustedFootprintSideFact; }
Fact* adjustedFootprintFrontal (void) { return &_adjustedFootprintFrontalFact; }
double imageFootprintSide (void) const { return _imageFootprintSide; }
double imageFootprintFrontal (void) const { return _imageFootprintFrontal; }
bool isManualCamera (void) { return cameraName() == manualCameraName(); }
double imageFootprintSide (void) const { return _imageFootprintSide; }
double imageFootprintFrontal (void) const { return _imageFootprintFrontal; }
bool dirty (void) const { return _dirty; }
void setDirty (bool dirty);
......
......@@ -302,6 +302,6 @@ void MissionSettingsItem::_setHomeAltFromTerrain(double terrainAltitude)
_plannedHomePositionAltitudeFact.setSendValueChangedSignals(false);
_plannedHomePositionAltitudeFact.setRawValue(terrainAltitude);
_plannedHomePositionAltitudeFact.clearDeferredValueChangeSignal();
_plannedHomePositionAltitudeFact.setSendValueChangedSignals(false);
_plannedHomePositionAltitudeFact.setSendValueChangedSignals(true);
}
}
......@@ -22,6 +22,7 @@
QGC_LOGGING_CATEGORY(StructureScanComplexItemLog, "StructureScanComplexItemLog")
const char* StructureScanComplexItem::_altitudeFactName = "Altitude";
const char* StructureScanComplexItem::_structureHeightFactName = "StructureHeight";
const char* StructureScanComplexItem::_layersFactName = "Layers";
const char* StructureScanComplexItem::_gimbalPitchFactName = "GimbalPitch";
const char* StructureScanComplexItem::_gimbalYawFactName = "GimbalYaw";
......@@ -71,6 +72,10 @@ StructureScanComplexItem::StructureScanComplexItem(Vehicle* vehicle, QObject* pa
connect(&_gimbalPitchFact, &Fact::valueChanged, this, &StructureScanComplexItem::_setDirty);
connect(&_gimbalYawFact, &Fact::valueChanged, this, &StructureScanComplexItem::_setDirty);
connect(&_layersFact, &Fact::valueChanged, this, &StructureScanComplexItem::_recalcLayerInfo);
connect(&_structureHeightFact, &Fact::valueChanged, this, &StructureScanComplexItem::_recalcLayerInfo);
connect(_cameraCalc.adjustedFootprintFrontal(), &Fact::valueChanged, this, &StructureScanComplexItem::_recalcLayerInfo);
connect(this, &StructureScanComplexItem::altitudeRelativeChanged, this, &StructureScanComplexItem::_setDirty);
connect(this, &StructureScanComplexItem::altitudeRelativeChanged, this, &StructureScanComplexItem::coordinateHasRelativeAltitudeChanged);
connect(this, &StructureScanComplexItem::altitudeRelativeChanged, this, &StructureScanComplexItem::exitCoordinateHasRelativeAltitudeChanged);
......@@ -89,6 +94,8 @@ StructureScanComplexItem::StructureScanComplexItem(Vehicle* vehicle, QObject* pa
connect(&_flightPolygon, &QGCMapPolygon::pathChanged, this, &StructureScanComplexItem::_recalcCameraShots);
connect(_cameraCalc.adjustedFootprintSide(), &Fact::valueChanged, this, &StructureScanComplexItem::_recalcCameraShots);
connect(&_layersFact, &Fact::valueChanged, this, &StructureScanComplexItem::_recalcCameraShots);
_recalcLayerInfo();
}
void StructureScanComplexItem::_setScanDistance(double scanDistance)
......@@ -143,13 +150,14 @@ void StructureScanComplexItem::save(QJsonArray& missionItems)
QJsonObject saveObject;
// Header
saveObject[JsonHelper::jsonVersionKey] = 1;
saveObject[JsonHelper::jsonVersionKey] = 2;
saveObject[VisualMissionItem::jsonTypeKey] = VisualMissionItem::jsonTypeComplexItemValue;
saveObject[ComplexMissionItem::jsonComplexItemTypeKey] = jsonComplexItemTypeValue;
saveObject[_gimbalPitchFactName] = _gimbalPitchFact.rawValue().toDouble();
saveObject[_gimbalYawFactName] = _gimbalYawFact.rawValue().toDouble();
saveObject[_altitudeFactName] = _altitudeFact.rawValue().toDouble();
saveObject[_structureHeightFactName] = _structureHeightFact.rawValue().toDouble();
saveObject[_jsonAltitudeRelativeKey] = _altitudeRelative;
saveObject[_layersFactName] = _layersFact.rawValue().toDouble();
......@@ -181,7 +189,8 @@ bool StructureScanComplexItem::load(const QJsonObject& complexObject, int sequen
{ _gimbalPitchFactName, QJsonValue::Double, true },
{ _gimbalYawFactName, QJsonValue::Double, true },
{ _altitudeFactName, QJsonValue::Double, true },
{ _jsonAltitudeRelativeKey, QJsonValue::Bool, false },
{ _structureHeightFactName, QJsonValue::Double, true },
{ _jsonAltitudeRelativeKey, QJsonValue::Bool, true },
{ _layersFactName, QJsonValue::Double, true },
{ _jsonCameraCalcKey, QJsonValue::Object, true },
};
......@@ -199,7 +208,7 @@ bool StructureScanComplexItem::load(const QJsonObject& complexObject, int sequen
}
int version = complexObject[JsonHelper::jsonVersionKey].toInt();
if (version != 1) {
if (version != 2) {
errorString = tr("%1 complex item version %2 not supported").arg(jsonComplexItemTypeValue).arg(version);
return false;
}
......@@ -273,7 +282,9 @@ void StructureScanComplexItem::appendMissionItems(QList<MissionItem*>& items, QO
for (int layer=0; layer<_layersFact.rawValue().toInt(); layer++) {
bool addTriggerStart = true;
double layerAltitude = baseAltitude + (layer * _cameraCalc.adjustedFootprintFrontal()->rawValue().toDouble());
// baseAltitude is the bottom of the first layer. Hence we need to move up half the distance of the camera footprint to center the camera
// within the layer.
double layerAltitude = baseAltitude + (_cameraCalc.adjustedFootprintFrontal()->rawValue().toDouble() / 2.0) + (layer * _cameraCalc.adjustedFootprintFrontal()->rawValue().toDouble());
for (int i=0; i<_flightPolygon.count(); i++) {
QGeoCoordinate vertexCoord = _flightPolygon.vertexCoordinate(i);
......@@ -449,3 +460,20 @@ void StructureScanComplexItem::setAltitudeRelative(bool altitudeRelative)
emit altitudeRelativeChanged(altitudeRelative);
}
}
void StructureScanComplexItem::_recalcLayerInfo(void)
{
if (_cameraCalc.isManualCamera()) {
// Structure height is calculated from layer count, layer height.
_structureHeightFact.setSendValueChangedSignals(false);
_structureHeightFact.setRawValue(_layersFact.rawValue().toInt() * _cameraCalc.adjustedFootprintFrontal()->rawValue().toDouble());
_structureHeightFact.clearDeferredValueChangeSignal();
_structureHeightFact.setSendValueChangedSignals(true);
} else {
// Layer count is calculated from structure and layer heights
_layersFact.setSendValueChangedSignals(false);
_layersFact.setRawValue(qCeil(_structureHeightFact.rawValue().toDouble() / _cameraCalc.adjustedFootprintFrontal()->rawValue().toDouble()));
_layersFact.clearDeferredValueChangeSignal();
_layersFact.setSendValueChangedSignals(true);
}
}
......@@ -31,6 +31,7 @@ public:
Q_PROPERTY(Fact* gimbalPitch READ gimbalPitch CONSTANT)
Q_PROPERTY(Fact* gimbalYaw READ gimbalYaw CONSTANT)
Q_PROPERTY(Fact* altitude READ altitude CONSTANT)
Q_PROPERTY(Fact* structureHeight READ structureHeight CONSTANT)
Q_PROPERTY(Fact* layers READ layers CONSTANT)
Q_PROPERTY(bool altitudeRelative READ altitudeRelative WRITE setAltitudeRelative NOTIFY altitudeRelativeChanged)
Q_PROPERTY(int cameraShots READ cameraShots NOTIFY cameraShotsChanged)
......@@ -41,6 +42,7 @@ public:
CameraCalc* cameraCalc (void) { return &_cameraCalc; }
Fact* altitude (void) { return &_altitudeFact; }
Fact* structureHeight (void) { return &_structureHeightFact; }
Fact* layers (void) { return &_layersFact; }
bool altitudeRelative (void) const { return _altitudeRelative; }
......@@ -110,6 +112,7 @@ private slots:
void _rebuildFlightPolygon (void);
void _recalcCameraShots (void);
void _resetGimbal (void);
void _recalcLayerInfo (void);
private:
void _setExitCoordinate(const QGeoCoordinate& coordinate);
......@@ -135,11 +138,13 @@ private:
static QMap<QString, FactMetaData*> _metaDataMap;
Fact _altitudeFact;
Fact _structureHeightFact;
Fact _layersFact;
Fact _gimbalPitchFact;
Fact _gimbalYawFact;
static const char* _altitudeFactName;
static const char* _structureHeightFactName;
static const char* _layersFactName;
static const char* _gimbalPitchFactName;
static const char* _gimbalYawFactName;
......
......@@ -248,6 +248,8 @@ Column {
}
// Calculated values
/*
Taking these out for now since they take up so much space. May come back at a later time.
GridLayout {
anchors.left: parent.left
anchors.right: parent.right
......@@ -269,6 +271,7 @@ Column {
enabled: false
}
} // GridLayout
*/
} // Column - Camera spec based ui
......
......@@ -57,6 +57,7 @@ QGCView {
property bool _singleComplexItem: _missionController.complexMissionItemNames.length === 1
property real _toolbarHeight: _qgcView.height - ScreenTools.availableHeight
property int _editingLayer: _layerMission
property int _toolStripBottom: toolStrip.height + toolStrip.y
readonly property int _layerMission: 1
readonly property int _layerGeoFence: 2
......@@ -732,7 +733,7 @@ QGCView {
anchors.bottom: waypointValuesDisplay.visible ? waypointValuesDisplay.top : parent.bottom
anchors.left: parent.left
mapControl: editorMap
visible: !ScreenTools.isTinyScreen
visible: _toolStripBottom < y
}
MissionItemStatus {
......@@ -743,7 +744,7 @@ QGCView {
maxWidth: parent.width - rightPanel.width - x
anchors.bottom: parent.bottom
missionItems: _missionController.visualItems
visible: _editingLayer === _layerMission && (ScreenTools.isMobile ? height < Screen.height * 0.25 : true)
visible: _editingLayer === _layerMission && (_toolStripBottom + mapScale.height) < y && QGroundControl.corePlugin.options.showMissionStatus
}
}
......
......@@ -87,7 +87,7 @@ Rectangle {
columnSpacing: ScreenTools.defaultFontPixelWidth / 2
rowSpacing: 0
columns: 3
enabled: missionItem.cameraCalc.cameraName === missionItem.cameraCalc.manualCameraName
visible: missionItem.cameraCalc.isManualCamera
Item { width: 1; height: 1 }
QGCLabel { text: qsTr("Pitch") }
......@@ -126,13 +126,27 @@ Rectangle {
rowSpacing: _margin
columns: 2
QGCLabel { text: qsTr("Layers") }
QGCLabel {
text: qsTr("Structure height")
visible: !missionItem.cameraCalc.isManualCamera
}
FactTextField {
fact: missionItem.structureHeight
Layout.fillWidth: true
visible: !missionItem.cameraCalc.isManualCamera
}
QGCLabel {
text: qsTr("# Layers")
visible: missionItem.cameraCalc.isManualCamera
}
FactTextField {
fact: missionItem.layers
Layout.fillWidth: true
visible: missionItem.cameraCalc.isManualCamera
}
QGCLabel { text: qsTr("Altitude") }
QGCLabel { text: qsTr("Bottom layer alt") }
FactTextField {
fact: missionItem.altitude
Layout.fillWidth: true
......
......@@ -128,7 +128,7 @@ Item {
fillMode: Image.PreserveAspectFit
anchors.left: parent.left
anchors.top: parent.top
visible: !isHidden && !inPopup && !ScreenTools.isMobile && enablePopup
visible: !isHidden && !inPopup && !ScreenTools.isMobile && enablePopup && pipMouseArea.containsMouse
height: ScreenTools.defaultFontPixelHeight * 2.5
width: ScreenTools.defaultFontPixelHeight * 2.5
sourceSize.height: height
......
......@@ -34,6 +34,7 @@ Rectangle {
readonly property real _buttonWidth: _defaultTextWidth * 18
readonly property string _armedVehicleText: qsTr("This operation cannot be performed while the vehicle is armed.")
property bool _vehicleArmed: QGroundControl.multiVehicleManager.activeVehicle ? QGroundControl.multiVehicleManager.activeVehicle.armed : false
property string _messagePanelText: qsTr("missing message panel text")
property bool _fullParameterVehicleAvailable: QGroundControl.multiVehicleManager.parameterReadyVehicleAvailable && !QGroundControl.multiVehicleManager.activeVehicle.parameterManager.missingParameters
property var _corePlugin: QGroundControl.corePlugin
......@@ -41,7 +42,7 @@ Rectangle {
function showSummaryPanel()
{
if (_fullParameterVehicleAvailable) {
if (QGroundControl.multiVehicleManager.activeVehicle.autopilot.vehicleComponents.length == 0) {
if (QGroundControl.multiVehicleManager.activeVehicle.autopilot.vehicleComponents.length === 0) {
panelLoader.setSourceComponent(noComponentsVehicleSummaryComponent)
} else {
panelLoader.setSource("VehicleSummary.qml")
......@@ -80,8 +81,7 @@ Rectangle {
var autopilotPlugin = QGroundControl.multiVehicleManager.activeVehicle.autopilot
var prereq = autopilotPlugin.prerequisiteSetup(vehicleComponent)
if (prereq !== "") {
//-- TODO: This cannot be translated when built this way.
_messagePanelText = prereq + " setup must be completed prior to " + vehicleComponent.name + " setup."
_messagePanelText = qsTr("%1 setup must be completed prior to %2 setup.").arg(prereq).arg(vehicleComponent.name)
panelLoader.setSourceComponent(messagePanelComponent)
} else {
panelLoader.setSource(vehicleComponent.setupSource, vehicleComponent)
......@@ -272,7 +272,7 @@ Rectangle {
setupIndicator: true
setupComplete: joystickManager.activeJoystick ? joystickManager.activeJoystick.calibrated : false
exclusiveGroup: setupButtonGroup
visible: _fullParameterVehicleAvailable && joystickManager.joysticks.length != 0
visible: _fullParameterVehicleAvailable && joystickManager.joysticks.length !== 0
text: qsTr("Joystick")
Layout.fillWidth: true
......@@ -289,7 +289,7 @@ Rectangle {
setupComplete: modelData.setupComplete
exclusiveGroup: setupButtonGroup
text: modelData.name
visible: modelData.setupSource.toString() != ""
visible: modelData.setupSource.toString() !== ""
Layout.fillWidth: true
onClicked: showVehicleComponentPanel(modelData)
......
......@@ -45,6 +45,7 @@ public:
Q_PROPERTY(bool showOfflineMapExport READ showOfflineMapExport NOTIFY showOfflineMapExportChanged)
Q_PROPERTY(bool showOfflineMapImport READ showOfflineMapImport NOTIFY showOfflineMapImportChanged)
Q_PROPERTY(bool useMobileFileDialog READ useMobileFileDialog CONSTANT)
Q_PROPERTY(bool showMissionStatus READ showMissionStatus CONSTANT)
/// Should QGC hide its settings menu and colapse it into one single menu (Settings and Vehicle Setup)?
/// @return true if QGC should consolidate both menus into one.
......@@ -62,6 +63,10 @@ public:
/// @return An alternate widget (see QGCInstrumentWidget.qml, the default widget)
virtual CustomInstrumentWidget* instrumentWidget();
/// Should the mission status indicator (Plan View) be shown?
/// @return Yes or no
virtual bool showMissionStatus () { return true; }
/// Allows access to the full fly view window
virtual QUrl flyViewOverlay () const { return QUrl(); }
/// By returning false you can hide the following sensor calibration pages
......
......@@ -135,6 +135,7 @@ MainWindow::MainWindow()
_ui.setupUi(this);
// Make sure tool bar elements all fit before changing minimum width
setMinimumWidth(1008);
setMinimumHeight(520);
configureWindowName();
// Setup central widget with a layout to hold the views
......
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