1
0
Fork 0

Launcher: fix helipad selection

Helipads were not being shown for convention airports, only for
heliports. Fix this up so helipads work alongside runways at
conventional airports, when the selected aircraft is a helicopter.
This commit is contained in:
James Turner 2020-07-13 14:28:53 +01:00
parent b08de513d0
commit 3993fc7d35
4 changed files with 112 additions and 34 deletions

View file

@ -258,6 +258,7 @@ void LocationController::setBaseLocation(QmlPositioned* pos)
// disable offset when selecting a heliport // disable offset when selecting a heliport
if (m_airportLocation->isHeliport()) { if (m_airportLocation->isHeliport()) {
m_onFinal = false; m_onFinal = false;
m_useActiveRunway = false;
} }
} else { } else {
m_airportLocation.clear(); m_airportLocation.clear();
@ -325,20 +326,25 @@ QObjectList LocationController::airportRunways() const
return {}; return {};
QObjectList result; QObjectList result;
if (m_airportLocation->isHeliport()) { for (unsigned int r = 0; r < m_airportLocation->numRunways(); ++r) {
// helipads
for (unsigned int r=0; r<m_airportLocation->numHelipads(); ++r) {
auto p = new QmlPositioned(m_airportLocation->getHelipadByIndex(r).ptr());
QQmlEngine::setObjectOwnership(p, QQmlEngine::JavaScriptOwnership);
result.push_back(p);
}
} else {
// regular runways
for (unsigned int r=0; r<m_airportLocation->numRunways(); ++r) {
auto p = new QmlPositioned(m_airportLocation->getRunwayByIndex(r).ptr()); auto p = new QmlPositioned(m_airportLocation->getRunwayByIndex(r).ptr());
QQmlEngine::setObjectOwnership(p, QQmlEngine::JavaScriptOwnership); QQmlEngine::setObjectOwnership(p, QQmlEngine::JavaScriptOwnership);
result.push_back(p); result.push_back(p);
} }
return result;
}
QObjectList LocationController::airportHelipads() const
{
if (!m_airportLocation)
return {};
QObjectList result;
for (unsigned int r = 0; r < m_airportLocation->numHelipads(); ++r) {
auto p = new QmlPositioned(m_airportLocation->getHelipadByIndex(r).ptr());
QQmlEngine::setObjectOwnership(p, QQmlEngine::JavaScriptOwnership);
result.push_back(p);
} }
return result; return result;
@ -564,12 +570,18 @@ void LocationController::restoreLocation(QVariantMap l)
if (l.contains("location-apt-runway")) { if (l.contains("location-apt-runway")) {
QString runway = l.value("location-apt-runway").toString().toUpper(); QString runway = l.value("location-apt-runway").toString().toUpper();
const auto runwayStr = runway.toStdString();
if (runway == QStringLiteral("ACTIVE")) { if (runway == QStringLiteral("ACTIVE")) {
m_useActiveRunway = true; m_useActiveRunway = true;
} else if (m_airportLocation->isHeliport()) { } else if (m_airportLocation->isHeliport()) {
m_detailLocation = m_airportLocation->getHelipadByIdent(runway.toStdString()); m_detailLocation = m_airportLocation->getHelipadByIdent(runwayStr);
} else { } else {
m_detailLocation = m_airportLocation->getRunwayByIdent(runway.toStdString()); // could be a helipad at a regular airport
if (m_airportLocation->hasHelipadWithIdent(runwayStr)) {
m_detailLocation = m_airportLocation->getHelipadByIdent(runwayStr);
} else {
m_detailLocation = m_airportLocation->getRunwayByIdent(runwayStr);
}
} }
} else if (l.contains("location-apt-parking")) { } else if (l.contains("location-apt-parking")) {
QString parking = l.value("location-apt-parking").toString(); QString parking = l.value("location-apt-parking").toString();
@ -646,7 +658,7 @@ QVariantMap LocationController::saveLocation() const
locationSet.insert("location-apt-parking", "AVAILABLE"); locationSet.insert("location-apt-parking", "AVAILABLE");
} else if (m_detailLocation) { } else if (m_detailLocation) {
const auto detailType = m_detailLocation->type(); const auto detailType = m_detailLocation->type();
if (detailType == FGPositioned::RUNWAY) { if ((detailType == FGPositioned::RUNWAY) || (detailType == FGPositioned::HELIPAD)) {
locationSet.insert("location-apt-runway", QString::fromStdString(m_detailLocation->ident())); locationSet.insert("location-apt-runway", QString::fromStdString(m_detailLocation->ident()));
} else if (detailType == FGPositioned::PARKING) { } else if (detailType == FGPositioned::PARKING) {
locationSet.insert("location-apt-parking", QString::fromStdString(m_detailLocation->ident())); locationSet.insert("location-apt-parking", QString::fromStdString(m_detailLocation->ident()));
@ -755,7 +767,7 @@ void LocationController::setLocationProperties()
fgSetString("/sim/presets/parkpos", "AVAILABLE"); fgSetString("/sim/presets/parkpos", "AVAILABLE");
} else if (onRunway) { } else if (onRunway) {
if (m_airportLocation->type() == FGPositioned::AIRPORT) { if (m_airportLocation->type() == FGPositioned::AIRPORT) {
// explicit runway choice // explicit runway choice (this also works for helipads)
fgSetString("/sim/presets/runway", m_detailLocation->ident() ); fgSetString("/sim/presets/runway", m_detailLocation->ident() );
fgSetBool("/sim/presets/runway-requested", true ); fgSetBool("/sim/presets/runway-requested", true );
@ -948,8 +960,9 @@ void LocationController::onCollectConfig()
if (m_airportLocation) { if (m_airportLocation) {
m_config->setArg("airport", QString::fromStdString(m_airportLocation->ident())); m_config->setArg("airport", QString::fromStdString(m_airportLocation->ident()));
const bool onRunway = (m_detailLocation && (m_detailLocation->type() == FGPositioned::RUNWAY)); const auto ty = m_detailLocation ? m_detailLocation->type() : FGPositioned::INVALID;
const bool atParking = (m_detailLocation && (m_detailLocation->type() == FGPositioned::PARKING)); const bool onRunway = (ty == FGPositioned::RUNWAY) || (ty == FGPositioned::HELIPAD);
const bool atParking = ty == FGPositioned::PARKING;
if (m_useActiveRunway) { if (m_useActiveRunway) {
// pick by default // pick by default
@ -1082,8 +1095,11 @@ QString LocationController::description() const
name = fixNavaidName(name); name = fixNavaidName(name);
if (m_airportLocation) { if (m_airportLocation) {
const bool onRunway = (m_detailLocation && (m_detailLocation->type() == FGPositioned::RUNWAY)); const auto ty = m_detailLocation ? m_detailLocation->type() : FGPositioned::INVALID;
const bool atParking = (m_detailLocation && (m_detailLocation->type() == FGPositioned::PARKING)); const bool onRunway = ty == FGPositioned::RUNWAY;
const bool onPad = ty == FGPositioned::HELIPAD;
const bool atParking = ty == FGPositioned::PARKING;
QString locationOnAirport; QString locationOnAirport;
if (m_useActiveRunway) { if (m_useActiveRunway) {
@ -1094,7 +1110,7 @@ QString LocationController::description() const
} }
} else if (m_useAvailableParking) { } else if (m_useAvailableParking) {
locationOnAirport = tr("at an available parking position"); locationOnAirport = tr("at an available parking position");
} if (onRunway) { } else if (onRunway) {
QString runwayName = QString("runway %1").arg(QString::fromStdString(m_detailLocation->ident())); QString runwayName = QString("runway %1").arg(QString::fromStdString(m_detailLocation->ident()));
if (m_onFinal) { if (m_onFinal) {
@ -1102,6 +1118,8 @@ QString LocationController::description() const
} else { } else {
locationOnAirport = tr("on %1").arg(runwayName); locationOnAirport = tr("on %1").arg(runwayName);
} }
} else if (onPad) {
locationOnAirport = tr("on pad %1").arg(QString::fromStdString(m_detailLocation->ident()));
} else if (atParking) { } else if (atParking) {
locationOnAirport = tr("at parking position %1").arg(QString::fromStdString(m_detailLocation->ident())); locationOnAirport = tr("at parking position %1").arg(QString::fromStdString(m_detailLocation->ident()));
} }

View file

@ -45,6 +45,7 @@ class LocationController : public QObject
Q_PROPERTY(QList<QObject*> airportRunways READ airportRunways NOTIFY baseLocationChanged) Q_PROPERTY(QList<QObject*> airportRunways READ airportRunways NOTIFY baseLocationChanged)
Q_PROPERTY(QList<QObject*> airportParkings READ airportParkings NOTIFY baseLocationChanged) Q_PROPERTY(QList<QObject*> airportParkings READ airportParkings NOTIFY baseLocationChanged)
Q_PROPERTY(QList<QObject*> airportHelipads READ airportHelipads NOTIFY baseLocationChanged)
Q_PROPERTY(bool offsetEnabled READ offsetEnabled WRITE setOffsetEnabled NOTIFY offsetChanged) Q_PROPERTY(bool offsetEnabled READ offsetEnabled WRITE setOffsetEnabled NOTIFY offsetChanged)
Q_PROPERTY(QuantityValue offsetRadial READ offsetRadial WRITE setOffsetRadial NOTIFY offsetChanged) Q_PROPERTY(QuantityValue offsetRadial READ offsetRadial WRITE setOffsetRadial NOTIFY offsetChanged)
@ -145,6 +146,7 @@ public:
Q_INVOKABLE void addToRecent(QmlPositioned* pos); Q_INVOKABLE void addToRecent(QmlPositioned* pos);
QObjectList airportRunways() const; QObjectList airportRunways() const;
QObjectList airportHelipads() const;
QObjectList airportParkings() const; QObjectList airportParkings() const;
Q_INVOKABLE void showHistoryInSearchModel(); Q_INVOKABLE void showHistoryInSearchModel();

View file

@ -166,6 +166,8 @@ void QmlPositioned::setInner(FGPositionedRef p)
} else { } else {
m_pos = p; m_pos = p;
} }
emit infoChanged();
} }
FGPositionedRef QmlPositioned::inner() const FGPositionedRef QmlPositioned::inner() const

View file

@ -24,7 +24,12 @@ Item {
if (pos === null) if (pos === null)
return; return;
console.info("Saw airport click on:" + pos.ident) // only allow selction of helipads if the aircraft type in
// use is a helicopter.
if ((pos.type == Positioned.Helipad) && (_launcher.aircraftType != LauncherController.Helicopter)) {
return;
}
_location.setDetailLocation(pos) _location.setDetailLocation(pos)
diagram.selection = pos diagram.selection = pos
syncUIFromController(); syncUIFromController();
@ -40,6 +45,9 @@ Item {
if (_location.useAvailableParking || (_location.detail.type === Positioned.Parking)) { if (_location.useAvailableParking || (_location.detail.type === Positioned.Parking)) {
parkingRadio.select() parkingRadio.select()
parkingChoice.syncCurrentIndex(); parkingChoice.syncCurrentIndex();
} else if (_location.detail.type === Positioned.Helipad) {
helipadRadio.select();
helipadChoice.syncCurrentIndex();
} else { } else {
runwayRadio.select(); runwayRadio.select();
runwayChoice.syncCurrentIndex(); runwayChoice.syncCurrentIndex();
@ -101,6 +109,7 @@ Item {
Row { Row {
width: parent.width width: parent.width
spacing: Style.margin spacing: Style.margin
visible: !root.isHeliport
RadioButton { RadioButton {
id: runwayRadio id: runwayRadio
@ -113,7 +122,7 @@ Item {
} }
StyledText { StyledText {
text: isHeliport ? qsTr("Pad") : qsTr("Runway") text: qsTr("Runway")
anchors.verticalCenter: parent.verticalCenter anchors.verticalCenter: parent.verticalCenter
} }
@ -165,15 +174,13 @@ Item {
ToggleBox { ToggleBox {
id: onFinalBox id: onFinalBox
visible: !root.isHeliport
anchors.left: parent.left anchors.left: parent.left
anchors.leftMargin: Style.strutSize anchors.leftMargin: Style.strutSize
height: onFinalContents.height + onFinalContents.y + Style.margin height: onFinalContents.height + onFinalContents.y + Style.margin
anchors.right: parent.right anchors.right: parent.right
anchors.rightMargin: Style.margin anchors.rightMargin: Style.margin
// no offset for helipads
visible: !isHeliport
enabled: runwayRadio.selected enabled: runwayRadio.selected
selected: _location.onFinal selected: _location.onFinal
@ -241,10 +248,8 @@ Item {
ToggleSwitch { ToggleSwitch {
x: Style.strutSize x: Style.strutSize
// no localizer for helipads
visible: !isHeliport
enabled:runwayRadio.selected enabled:runwayRadio.selected
visible: !root.isHeliport
// enable if selected runway has ILS // enable if selected runway has ILS
label: qsTr("Tune navigation radio (NAV1) to runway localizer") label: qsTr("Tune navigation radio (NAV1) to runway localizer")
checked: _location.tuneNAV1 checked: _location.tuneNAV1
@ -254,6 +259,59 @@ Item {
} }
} }
// helipads row
Row {
width: parent.width
spacing: Style.margin
visible: (_launcher.aircraftType === LauncherController.Helicopter) && ( _location.airportHelipads.length > 0)
RadioButton {
id: helipadRadio
anchors.verticalCenter: parent.verticalCenter
group: radioGroup
onClicked: {
if (selected) helipadChoice.setLocation();
}
}
StyledText {
text: qsTr("Pad")
anchors.verticalCenter: parent.verticalCenter
}
PopupChoice {
id: helipadChoice
model: _location.airportHelipads
displayRole: "ident"
width: parent.width * 0.5
anchors.verticalCenter: parent.verticalCenter
enabled: helipadRadio.selected
onCurrentIndexChanged: {
setLocation();
}
function setLocation()
{
_location.setDetailLocation(_location.airportHelipads[currentIndex])
diagram.selection = _location.airportHelipads[currentIndex]
}
function syncCurrentIndex()
{
for (var i=0; i < _location.airportHelipads.length; ++i) {
if (_location.airportHelipads[i].equals(_location.detail)) {
currentIndex = i;
return;
}
}
currentIndex = 0;
}
}
}
// parking row // parking row
Row { Row {
width: parent.width width: parent.width
@ -293,14 +351,12 @@ Item {
function syncCurrentIndex() function syncCurrentIndex()
{ {
if (_location.useAvailableParking) { if (_location.useAvailableParking) {
console.info("Parking: controller says use available")
currentIndex = -1; currentIndex = -1;
return; return;
} }
for (var i=0; i < _location.airportParkings.length; ++i) { for (var i=0; i < _location.airportParkings.length; ++i) {
if (_location.airportParkings[i].equals(_location.detail)) { if (_location.airportParkings[i].equals(_location.detail)) {
console.info("Found explicit parking " + _location.detail.ident + " at index " + i);
currentIndex = i; currentIndex = i;
return; return;
} }