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:
parent
b08de513d0
commit
3993fc7d35
4 changed files with 112 additions and 34 deletions
|
@ -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()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue