Launcher: location page in QtQuick
This moves the last page into QQ2 implementation, in preparation for making the top-level UI be a QQuickWindow.
This commit is contained in:
parent
7e8b1b67e7
commit
b2f90fbfa4
34 changed files with 3168 additions and 2034 deletions
|
@ -16,8 +16,10 @@ using namespace flightgear;
|
||||||
* FGTaxiNode
|
* FGTaxiNode
|
||||||
*************************************************************************/
|
*************************************************************************/
|
||||||
|
|
||||||
FGTaxiNode::FGTaxiNode(int index, const SGGeod& pos, bool aOnRunway, int aHoldType) :
|
FGTaxiNode::FGTaxiNode(int index, const SGGeod& pos,
|
||||||
FGPositioned(TRANSIENT_ID, FGPositioned::PARKING, "", pos),
|
bool aOnRunway, int aHoldType,
|
||||||
|
const std::string& ident) :
|
||||||
|
FGPositioned(TRANSIENT_ID, FGPositioned::PARKING, ident, pos),
|
||||||
m_index(index),
|
m_index(index),
|
||||||
isOnRunway(aOnRunway),
|
isOnRunway(aOnRunway),
|
||||||
holdType(aHoldType),
|
holdType(aHoldType),
|
||||||
|
|
|
@ -31,7 +31,8 @@ protected:
|
||||||
bool m_isPushback;
|
bool m_isPushback;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
FGTaxiNode(int index, const SGGeod& pos, bool aOnRunway, int aHoldType);
|
FGTaxiNode(int index, const SGGeod& pos, bool aOnRunway, int aHoldType,
|
||||||
|
const std::string& ident = {});
|
||||||
virtual ~FGTaxiNode();
|
virtual ~FGTaxiNode();
|
||||||
|
|
||||||
void setElevation(double val);
|
void setElevation(double val);
|
||||||
|
|
|
@ -42,10 +42,9 @@ FGParking::FGParking(int index,
|
||||||
const std::string& name,
|
const std::string& name,
|
||||||
const std::string& aType,
|
const std::string& aType,
|
||||||
const std::string& codes) :
|
const std::string& codes) :
|
||||||
FGTaxiNode(index, pos, false, 0),
|
FGTaxiNode(index, pos, false, 0, name),
|
||||||
heading(aHeading),
|
heading(aHeading),
|
||||||
radius(aRadius),
|
radius(aRadius),
|
||||||
parkingName(name),
|
|
||||||
type(aType),
|
type(aType),
|
||||||
airlineCodes(codes)
|
airlineCodes(codes)
|
||||||
{
|
{
|
||||||
|
|
|
@ -42,7 +42,6 @@ class FGParking : public FGTaxiNode
|
||||||
private:
|
private:
|
||||||
const double heading;
|
const double heading;
|
||||||
const double radius;
|
const double radius;
|
||||||
const std::string parkingName;
|
|
||||||
const std::string type;
|
const std::string type;
|
||||||
const std::string airlineCodes;
|
const std::string airlineCodes;
|
||||||
FGTaxiNodeRef pushBackPoint;
|
FGTaxiNodeRef pushBackPoint;
|
||||||
|
@ -64,10 +63,7 @@ public:
|
||||||
|
|
||||||
std::string getType () const { return type; };
|
std::string getType () const { return type; };
|
||||||
std::string getCodes () const { return airlineCodes;};
|
std::string getCodes () const { return airlineCodes;};
|
||||||
std::string getName () const { return parkingName; };
|
std::string getName () const { return ident(); };
|
||||||
|
|
||||||
// TODO do parkings have different name and ident?
|
|
||||||
virtual const std::string& name() const { return parkingName; }
|
|
||||||
|
|
||||||
void setPushBackPoint(const FGTaxiNodeRef& node);
|
void setPushBackPoint(const FGTaxiNodeRef& node);
|
||||||
FGTaxiNodeRef getPushBackPoint () { return pushBackPoint; };
|
FGTaxiNodeRef getPushBackPoint () { return pushBackPoint; };
|
||||||
|
|
|
@ -33,8 +33,12 @@
|
||||||
#include <Airports/runways.hxx>
|
#include <Airports/runways.hxx>
|
||||||
#include <Airports/parking.hxx>
|
#include <Airports/parking.hxx>
|
||||||
#include <Airports/pavement.hxx>
|
#include <Airports/pavement.hxx>
|
||||||
|
#include <Airports/groundnetwork.hxx>
|
||||||
|
|
||||||
#include <Navaids/navrecord.hxx>
|
#include <Navaids/navrecord.hxx>
|
||||||
|
#include <Navaids/NavDataCache.hxx>
|
||||||
|
|
||||||
|
#include "QmlPositioned.hxx"
|
||||||
|
|
||||||
static double distanceToLineSegment(const QVector2D& p, const QVector2D& a,
|
static double distanceToLineSegment(const QVector2D& p, const QVector2D& a,
|
||||||
const QVector2D& b, double* outT = NULL)
|
const QVector2D& b, double* outT = NULL)
|
||||||
|
@ -86,7 +90,7 @@ static double unitLengthAfterMapping(const QTransform& t)
|
||||||
return QVector2D(tVec).length();
|
return QVector2D(tVec).length();
|
||||||
}
|
}
|
||||||
|
|
||||||
AirportDiagram::AirportDiagram(QWidget* pr) :
|
AirportDiagram::AirportDiagram(QQuickItem* pr) :
|
||||||
BaseDiagram(pr),
|
BaseDiagram(pr),
|
||||||
m_approachDistanceNm(-1.0)
|
m_approachDistanceNm(-1.0)
|
||||||
{
|
{
|
||||||
|
@ -133,10 +137,29 @@ void AirportDiagram::setAirport(FGAirportRef apt)
|
||||||
m_airport = apt;
|
m_airport = apt;
|
||||||
m_projectionCenter = apt ? apt->geod() : SGGeod();
|
m_projectionCenter = apt ? apt->geod() : SGGeod();
|
||||||
m_runways.clear();
|
m_runways.clear();
|
||||||
m_approachDistanceNm = -1.0; m_parking.clear();
|
m_parking.clear();
|
||||||
m_helipads.clear();
|
m_helipads.clear();
|
||||||
|
|
||||||
if (apt) {
|
if (apt) {
|
||||||
|
if (apt->type() == FGPositioned::HELIPORT) {
|
||||||
|
for (unsigned int r=0; r<apt->numHelipads(); ++r) {
|
||||||
|
FGHelipadRef pad = apt->getHelipadByIndex(r);
|
||||||
|
// add pad with index as data role
|
||||||
|
addHelipad(pad);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (unsigned int r=0; r<apt->numRunways(); ++r) {
|
||||||
|
addRunway(apt->getRunwayByIndex(r));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FGGroundNetwork* ground = apt->groundNetwork();
|
||||||
|
if (ground && ground->exists()) {
|
||||||
|
for (auto park : ground->allParkings()) {
|
||||||
|
addParking(park);
|
||||||
|
}
|
||||||
|
} // of was able to get ground-network
|
||||||
|
|
||||||
buildTaxiways();
|
buildTaxiways();
|
||||||
buildPavements();
|
buildPavements();
|
||||||
}
|
}
|
||||||
|
@ -148,48 +171,23 @@ void AirportDiagram::setAirport(FGAirportRef apt)
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
FGRunwayRef AirportDiagram::selectedRunway() const
|
void AirportDiagram::setSelection(QmlPositioned* pos)
|
||||||
{
|
{
|
||||||
return m_selectedRunway;
|
if (pos && (m_selection == pos->inner())) {
|
||||||
}
|
|
||||||
|
|
||||||
void AirportDiagram::setSelectedRunway(FGRunwayRef r)
|
|
||||||
{
|
|
||||||
if (r == m_selectedRunway) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_selectedParking.clear();
|
if (!pos) {
|
||||||
m_selectedHelipad.clear();
|
m_selection.clear();
|
||||||
m_selectedRunway = r;
|
} else {
|
||||||
update();
|
m_selection = pos->inner();
|
||||||
}
|
|
||||||
|
|
||||||
void AirportDiagram::setSelectedHelipad(FGHelipadRef pad)
|
|
||||||
{
|
|
||||||
if (pad == m_selectedHelipad) {
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
|
emit selectionChanged();
|
||||||
m_selectedParking.clear();
|
recomputeBounds(true);
|
||||||
m_selectedRunway.clear();
|
|
||||||
m_selectedHelipad = pad;
|
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AirportDiagram::setSelectedParking(FGParkingRef park)
|
void AirportDiagram::setApproachExtensionNm(double distanceNm)
|
||||||
{
|
|
||||||
if (m_selectedParking == park) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_selectedRunway.clear();
|
|
||||||
m_selectedHelipad.clear();
|
|
||||||
m_selectedParking = park;
|
|
||||||
update();
|
|
||||||
}
|
|
||||||
|
|
||||||
void AirportDiagram::setApproachExtensionDistance(double distanceNm)
|
|
||||||
{
|
{
|
||||||
if (m_approachDistanceNm == distanceNm) {
|
if (m_approachDistanceNm == distanceNm) {
|
||||||
return;
|
return;
|
||||||
|
@ -198,6 +196,38 @@ void AirportDiagram::setApproachExtensionDistance(double distanceNm)
|
||||||
m_approachDistanceNm = distanceNm;
|
m_approachDistanceNm = distanceNm;
|
||||||
recomputeBounds(true);
|
recomputeBounds(true);
|
||||||
update();
|
update();
|
||||||
|
emit approachExtensionChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
double AirportDiagram::approachExtensionNm() const
|
||||||
|
{
|
||||||
|
return m_approachDistanceNm;
|
||||||
|
}
|
||||||
|
|
||||||
|
QmlPositioned* AirportDiagram::selection() const
|
||||||
|
{
|
||||||
|
if (!m_selection)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return new QmlPositioned{m_selection};
|
||||||
|
}
|
||||||
|
|
||||||
|
qlonglong AirportDiagram::airportGuid() const
|
||||||
|
{
|
||||||
|
if (!m_airport)
|
||||||
|
return 0;
|
||||||
|
return m_airport->guid();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AirportDiagram::setAirportGuid(qlonglong guid)
|
||||||
|
{
|
||||||
|
if (guid == -1) {
|
||||||
|
m_airport.clear();
|
||||||
|
} else {
|
||||||
|
m_airport = fgpositioned_cast<FGAirport>(flightgear::NavDataCache::instance()->loadById(guid));
|
||||||
|
}
|
||||||
|
setAirport(m_airport);
|
||||||
|
emit airportChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void AirportDiagram::addRunway(FGRunwayRef rwy)
|
void AirportDiagram::addRunway(FGRunwayRef rwy)
|
||||||
|
@ -233,16 +263,17 @@ void AirportDiagram::doComputeBounds()
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_FOREACH(const ParkingData& p, m_parking) {
|
Q_FOREACH(const ParkingData& p, m_parking) {
|
||||||
extendBounds(p.pt);
|
extendBounds(p.pt, 10.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_FOREACH(const HelipadData& p, m_helipads) {
|
Q_FOREACH(const HelipadData& p, m_helipads) {
|
||||||
extendBounds(p.pt);
|
extendBounds(p.pt, 20.0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_selectedRunway && (m_approachDistanceNm > 0.0)) {
|
FGRunway* runwaySelection = fgpositioned_cast<FGRunway>(m_selection);
|
||||||
|
if (runwaySelection && (m_approachDistanceNm > 0.0)) {
|
||||||
double d = SG_NM_TO_METER * m_approachDistanceNm;
|
double d = SG_NM_TO_METER * m_approachDistanceNm;
|
||||||
QPointF pt = project(m_selectedRunway->pointOnCenterline(-d));
|
QPointF pt = project(runwaySelection->pointOnCenterline(-d));
|
||||||
extendBounds(pt);
|
extendBounds(pt);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -263,11 +294,9 @@ void AirportDiagram::addHelipad(FGHelipadRef pad)
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void AirportDiagram::paintContents(QPainter* p)
|
void AirportDiagram::paintContents(QPainter* p)
|
||||||
{
|
{
|
||||||
QTransform t = p->transform();
|
QTransform t = p->transform();
|
||||||
|
|
||||||
// pavements
|
// pavements
|
||||||
QBrush brush(QColor(0x9f, 0x9f, 0x9f));
|
QBrush brush(QColor(0x9f, 0x9f, 0x9f));
|
||||||
Q_FOREACH(const QPainterPath& path, m_pavements) {
|
Q_FOREACH(const QPainterPath& path, m_pavements) {
|
||||||
|
@ -305,11 +334,13 @@ void AirportDiagram::paintContents(QPainter* p)
|
||||||
SGGeod aircraftPos;
|
SGGeod aircraftPos;
|
||||||
int headingDeg;
|
int headingDeg;
|
||||||
|
|
||||||
|
FGRunway* runwaySelection = fgpositioned_cast<FGRunway>(m_selection);
|
||||||
|
|
||||||
// now draw the runways for real
|
// now draw the runways for real
|
||||||
Q_FOREACH(const RunwayData& r, m_runways) {
|
Q_FOREACH(const RunwayData& r, m_runways) {
|
||||||
|
|
||||||
QColor color(Qt::magenta);
|
QColor color(Qt::magenta);
|
||||||
if ((r.runway == m_selectedRunway) || (r.runway->reciprocalRunway() == m_selectedRunway)) {
|
if ((r.runway == runwaySelection) || (r.runway->reciprocalRunway() == runwaySelection)) {
|
||||||
color = Qt::yellow;
|
color = Qt::yellow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,7 +360,7 @@ void AirportDiagram::paintContents(QPainter* p)
|
||||||
// invert scaling factor so we can use screen pixel sizes here
|
// invert scaling factor so we can use screen pixel sizes here
|
||||||
p->scale(1.0 / m_scale, 1.0/ m_scale);
|
p->scale(1.0 / m_scale, 1.0/ m_scale);
|
||||||
|
|
||||||
p->setPen((r.runway == m_selectedRunway) ? Qt::yellow : Qt::magenta);
|
p->setPen((r.runway == runwaySelection) ? Qt::yellow : Qt::magenta);
|
||||||
p->drawText(QRect(-100, 5, 200, 200), ident, Qt::AlignHCenter | Qt::AlignTop);
|
p->drawText(QRect(-100, 5, 200, 200), ident, Qt::AlignHCenter | Qt::AlignTop);
|
||||||
|
|
||||||
FGRunway* recip = r.runway->reciprocalRunway();
|
FGRunway* recip = r.runway->reciprocalRunway();
|
||||||
|
@ -340,28 +371,28 @@ void AirportDiagram::paintContents(QPainter* p)
|
||||||
p->rotate(recip->headingDeg());
|
p->rotate(recip->headingDeg());
|
||||||
p->scale(1.0 / m_scale, 1.0/ m_scale);
|
p->scale(1.0 / m_scale, 1.0/ m_scale);
|
||||||
|
|
||||||
p->setPen((r.runway->reciprocalRunway() == m_selectedRunway) ? Qt::yellow : Qt::magenta);
|
p->setPen((r.runway->reciprocalRunway() == runwaySelection) ? Qt::yellow : Qt::magenta);
|
||||||
p->drawText(QRect(-100, 5, 200, 200), recipIdent, Qt::AlignHCenter | Qt::AlignTop);
|
p->drawText(QRect(-100, 5, 200, 200), recipIdent, Qt::AlignHCenter | Qt::AlignTop);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_selectedRunway) {
|
if (runwaySelection) {
|
||||||
drawAircraft = true;
|
drawAircraft = true;
|
||||||
aircraftPos = m_selectedRunway->geod();
|
aircraftPos = runwaySelection->geod();
|
||||||
headingDeg = m_selectedRunway->headingDeg();
|
headingDeg = runwaySelection->headingDeg();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_selectedRunway && (m_approachDistanceNm > 0.0)) {
|
if (runwaySelection && (m_approachDistanceNm > 0.0)) {
|
||||||
p->setTransform(t);
|
p->setTransform(t);
|
||||||
// draw approach extension point
|
// draw approach extension point
|
||||||
double d = SG_NM_TO_METER * m_approachDistanceNm;
|
double d = SG_NM_TO_METER * m_approachDistanceNm;
|
||||||
QPointF pt = project(m_selectedRunway->pointOnCenterline(-d));
|
QPointF pt = project(runwaySelection->pointOnCenterline(-d));
|
||||||
QPointF pt2 = project(m_selectedRunway->geod());
|
QPointF pt2 = project(runwaySelection->geod());
|
||||||
QPen pen(Qt::yellow);
|
QPen pen(Qt::yellow);
|
||||||
pen.setWidth(2.0 / m_scale);
|
pen.setWidth(2.0 / m_scale);
|
||||||
p->setPen(pen);
|
p->setPen(pen);
|
||||||
p->drawLine(pt, pt2);
|
p->drawLine(pt, pt2);
|
||||||
|
|
||||||
aircraftPos = m_selectedRunway->pointOnCenterline(-d);
|
aircraftPos = runwaySelection->pointOnCenterline(-d);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (drawAircraft) {
|
if (drawAircraft) {
|
||||||
|
@ -388,23 +419,26 @@ void AirportDiagram::paintContents(QPainter* p)
|
||||||
|
|
||||||
void AirportDiagram::drawHelipads(QPainter* painter)
|
void AirportDiagram::drawHelipads(QPainter* painter)
|
||||||
{
|
{
|
||||||
QTransform t = painter->transform();
|
FGHelipad* selectedHelipad = fgpositioned_cast<FGHelipad>(m_selection);
|
||||||
|
|
||||||
Q_FOREACH(const HelipadData& p, m_helipads) {
|
Q_FOREACH(const HelipadData& p, m_helipads) {
|
||||||
painter->setTransform(t);
|
painter->save();
|
||||||
painter->translate(p.pt);
|
painter->translate(p.pt);
|
||||||
|
|
||||||
if (p.helipad == m_selectedHelipad) {
|
if (p.helipad == selectedHelipad) {
|
||||||
painter->setBrush(Qt::yellow);
|
painter->setBrush(Qt::yellow);
|
||||||
} else {
|
} else {
|
||||||
painter->setBrush(Qt::magenta);
|
painter->setBrush(Qt::magenta);
|
||||||
}
|
}
|
||||||
|
|
||||||
painter->drawPath(m_helipadIconPath);
|
painter->drawPath(m_helipadIconPath);
|
||||||
|
painter->restore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void AirportDiagram::drawParking(QPainter* painter, const ParkingData& p) const
|
void AirportDiagram::drawParking(QPainter* painter, const ParkingData& p) const
|
||||||
{
|
{
|
||||||
|
painter->save();
|
||||||
painter->translate(p.pt);
|
painter->translate(p.pt);
|
||||||
|
|
||||||
double hdg = p.parking->getHeading();
|
double hdg = p.parking->getHeading();
|
||||||
|
@ -420,8 +454,10 @@ void AirportDiagram::drawParking(QPainter* painter, const ParkingData& p) const
|
||||||
}
|
}
|
||||||
|
|
||||||
painter->rotate(hdg);
|
painter->rotate(hdg);
|
||||||
|
painter->setPen(Qt::NoPen);
|
||||||
|
|
||||||
if (p.parking == m_selectedParking) {
|
FGParking* selectedParking = fgpositioned_cast<FGParking>(m_selection);
|
||||||
|
if (p.parking == selectedParking) {
|
||||||
painter->setBrush(Qt::yellow);
|
painter->setBrush(Qt::yellow);
|
||||||
} else {
|
} else {
|
||||||
painter->setBrush(QColor(255, 196, 196)); // kind of pink
|
painter->setBrush(QColor(255, 196, 196)); // kind of pink
|
||||||
|
@ -431,7 +467,7 @@ void AirportDiagram::drawParking(QPainter* painter, const ParkingData& p) const
|
||||||
|
|
||||||
// ensure the selection colour is quite visible, by not filling
|
// ensure the selection colour is quite visible, by not filling
|
||||||
// with white when selected
|
// with white when selected
|
||||||
if (p.parking != m_selectedParking) {
|
if (p.parking != selectedParking) {
|
||||||
painter->fillRect(labelRect, Qt::white);
|
painter->fillRect(labelRect, Qt::white);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -450,39 +486,39 @@ void AirportDiagram::drawParking(QPainter* painter, const ParkingData& p) const
|
||||||
// draw text
|
// draw text
|
||||||
painter->setPen(Qt::black);
|
painter->setPen(Qt::black);
|
||||||
painter->drawText(labelRect, textFlags, parkingName);
|
painter->drawText(labelRect, textFlags, parkingName);
|
||||||
|
painter->restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
AirportDiagram::ParkingData AirportDiagram::findParkingData(const FGParkingRef &pk) const
|
AirportDiagram::ParkingData AirportDiagram::findParkingData(const FGParkingRef &pk) const
|
||||||
{
|
{
|
||||||
|
FGParking* selectedParking = fgpositioned_cast<FGParking>(m_selection);
|
||||||
|
if (!selectedParking)
|
||||||
|
return {};
|
||||||
|
|
||||||
Q_FOREACH(const ParkingData& p, m_parking) {
|
Q_FOREACH(const ParkingData& p, m_parking) {
|
||||||
if (p.parking == m_selectedParking) {
|
if (p.parking == selectedParking) {
|
||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return ParkingData();
|
return {};
|
||||||
}
|
}
|
||||||
|
|
||||||
void AirportDiagram::drawParkings(QPainter* painter) const
|
void AirportDiagram::drawParkings(QPainter* painter) const
|
||||||
{
|
{
|
||||||
painter->save();
|
FGParking* selectedParking = fgpositioned_cast<FGParking>(m_selection);
|
||||||
QTransform t = painter->transform();
|
|
||||||
|
|
||||||
Q_FOREACH(const ParkingData& p, m_parking) {
|
Q_FOREACH(const ParkingData& p, m_parking) {
|
||||||
if (p.parking == m_selectedParking) {
|
if (p.parking == selectedParking) {
|
||||||
continue; // skip and draw last
|
continue; // skip and draw last
|
||||||
}
|
}
|
||||||
|
|
||||||
painter->setTransform(t);
|
|
||||||
drawParking(painter, p);
|
drawParking(painter, p);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_selectedParking) {
|
if (selectedParking) {
|
||||||
painter->setTransform(t);
|
drawParking(painter, findParkingData(selectedParking));
|
||||||
drawParking(painter, findParkingData(m_selectedParking));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
painter->restore();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void AirportDiagram::drawILS(QPainter* painter, FGRunwayRef runway) const
|
void AirportDiagram::drawILS(QPainter* painter, FGRunwayRef runway) const
|
||||||
|
@ -514,12 +550,14 @@ void AirportDiagram::drawILS(QPainter* painter, FGRunwayRef runway) const
|
||||||
|
|
||||||
void AirportDiagram::mouseReleaseEvent(QMouseEvent* me)
|
void AirportDiagram::mouseReleaseEvent(QMouseEvent* me)
|
||||||
{
|
{
|
||||||
if (me->button() != Qt::LeftButton) {
|
me->accept();
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
QTransform t(transform());
|
QTransform t(transform());
|
||||||
double minWidth = 8.0 * unitLengthAfterMapping(t.inverted());
|
double minWidth = 8.0 * unitLengthAfterMapping(t.inverted());
|
||||||
|
#if 0
|
||||||
|
QImage img(width(), height(), QImage::Format_ARGB32);
|
||||||
|
QPainter imgPaint(&img);
|
||||||
|
imgPaint.setPen(QPen(Qt::cyan, 1));
|
||||||
|
#endif
|
||||||
|
|
||||||
Q_FOREACH(const RunwayData& r, m_runways) {
|
Q_FOREACH(const RunwayData& r, m_runways) {
|
||||||
QPainterPath pp = pathForRunway(r, t, minWidth);
|
QPainterPath pp = pathForRunway(r, t, minWidth);
|
||||||
|
@ -528,11 +566,8 @@ void AirportDiagram::mouseReleaseEvent(QMouseEvent* me)
|
||||||
QPointF p1(t.map(r.p1)), p2(t.map(r.p2));
|
QPointF p1(t.map(r.p1)), p2(t.map(r.p2));
|
||||||
double param;
|
double param;
|
||||||
distanceToLineSegment(QVector2D(me->pos()), QVector2D(p1), QVector2D(p2), ¶m);
|
distanceToLineSegment(QVector2D(me->pos()), QVector2D(p1), QVector2D(p2), ¶m);
|
||||||
if (param > 0.5) {
|
const FGRunwayRef clickedRunway = (param > 0.5) ? FGRunwayRef{r.runway->reciprocalRunway()} : r.runway;
|
||||||
emit clickedRunway(r.runway->reciprocalRunway());
|
emit clicked(new QmlPositioned{clickedRunway});
|
||||||
} else {
|
|
||||||
emit clickedRunway(r.runway);
|
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} // of runways iteration
|
} // of runways iteration
|
||||||
|
@ -540,18 +575,22 @@ void AirportDiagram::mouseReleaseEvent(QMouseEvent* me)
|
||||||
Q_FOREACH(const ParkingData& parking, m_parking) {
|
Q_FOREACH(const ParkingData& parking, m_parking) {
|
||||||
QPainterPath pp = pathForParking(parking, t);
|
QPainterPath pp = pathForParking(parking, t);
|
||||||
if (pp.contains(me->pos())) {
|
if (pp.contains(me->pos())) {
|
||||||
emit clickedParking(parking.parking);
|
emit clicked(new QmlPositioned{parking.parking});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Q_FOREACH(const HelipadData& pad, m_helipads) {
|
Q_FOREACH(const HelipadData& pad, m_helipads) {
|
||||||
QPainterPath pp = pathForHelipad(pad, t);
|
QPainterPath pp = pathForHelipad(pad, t);
|
||||||
|
//imgPaint.drawPath(pp);
|
||||||
if (pp.contains(me->pos())) {
|
if (pp.contains(me->pos())) {
|
||||||
emit clickedHelipad(pad.helipad);
|
emit clicked(new QmlPositioned{pad.helipad});
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
|
img.save("/Users/jmt/Desktop/img.png");
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
QPainterPath AirportDiagram::pathForRunway(const RunwayData& r, const QTransform& t,
|
QPainterPath AirportDiagram::pathForRunway(const RunwayData& r, const QTransform& t,
|
||||||
|
|
|
@ -23,15 +23,25 @@
|
||||||
|
|
||||||
#include "BaseDiagram.hxx"
|
#include "BaseDiagram.hxx"
|
||||||
|
|
||||||
|
#include <QPixmap>
|
||||||
|
|
||||||
#include <Airports/parking.hxx>
|
#include <Airports/parking.hxx>
|
||||||
#include <Airports/runways.hxx>
|
#include <Airports/runways.hxx>
|
||||||
#include <simgear/math/sg_geodesy.hxx>
|
#include <simgear/math/sg_geodesy.hxx>
|
||||||
|
|
||||||
|
// forward decls
|
||||||
|
class QmlPositioned;
|
||||||
|
|
||||||
class AirportDiagram : public BaseDiagram
|
class AirportDiagram : public BaseDiagram
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PROPERTY(QmlPositioned* selection READ selection WRITE setSelection NOTIFY selectionChanged)
|
||||||
|
Q_PROPERTY(qlonglong airport READ airportGuid WRITE setAirportGuid NOTIFY airportChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(double approachExtensionNm READ approachExtensionNm WRITE setApproachExtensionNm NOTIFY approachExtensionChanged)
|
||||||
public:
|
public:
|
||||||
AirportDiagram(QWidget* pr);
|
AirportDiagram(QQuickItem* pr = nullptr);
|
||||||
virtual ~AirportDiagram();
|
virtual ~AirportDiagram();
|
||||||
|
|
||||||
void setAirport(FGAirportRef apt);
|
void setAirport(FGAirportRef apt);
|
||||||
|
@ -40,24 +50,30 @@ public:
|
||||||
void addParking(FGParkingRef park);
|
void addParking(FGParkingRef park);
|
||||||
void addHelipad(FGHelipadRef pad);
|
void addHelipad(FGHelipadRef pad);
|
||||||
|
|
||||||
FGRunwayRef selectedRunway() const;
|
QmlPositioned* selection() const;
|
||||||
void setSelectedRunway(FGRunwayRef r);
|
|
||||||
|
|
||||||
void setSelectedHelipad(FGHelipadRef pad);
|
void setSelection(QmlPositioned* pos);
|
||||||
void setSelectedParking(FGParkingRef park);
|
|
||||||
|
void setApproachExtensionNm(double distanceNm);
|
||||||
|
double approachExtensionNm() const;
|
||||||
|
|
||||||
|
qlonglong airportGuid() const;
|
||||||
|
void setAirportGuid(qlonglong guid);
|
||||||
|
|
||||||
void setApproachExtensionDistance(double distanceNm);
|
|
||||||
Q_SIGNALS:
|
Q_SIGNALS:
|
||||||
void clickedRunway(FGRunwayRef rwy);
|
void clicked(QmlPositioned* pos);
|
||||||
void clickedHelipad(FGHelipadRef pad);
|
|
||||||
void clickedParking(FGParkingRef park);
|
void selectionChanged();
|
||||||
|
void airportChanged();
|
||||||
|
void approachExtensionChanged();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
virtual void mouseReleaseEvent(QMouseEvent* me);
|
void mouseReleaseEvent(QMouseEvent* me) override;
|
||||||
|
|
||||||
void paintContents(QPainter*) Q_DECL_OVERRIDE;
|
void paintContents(QPainter*) override;
|
||||||
|
|
||||||
void doComputeBounds() Q_DECL_OVERRIDE;
|
void doComputeBounds() override;
|
||||||
private:
|
private:
|
||||||
struct RunwayData {
|
struct RunwayData {
|
||||||
QPointF p1, p2;
|
QPointF p1, p2;
|
||||||
|
@ -115,11 +131,9 @@ private:
|
||||||
QPainterPath m_parkingIconPath, // arrow points right
|
QPainterPath m_parkingIconPath, // arrow points right
|
||||||
m_parkingIconLeftPath; // arrow points left
|
m_parkingIconLeftPath; // arrow points left
|
||||||
double m_approachDistanceNm;
|
double m_approachDistanceNm;
|
||||||
FGRunwayRef m_selectedRunway;
|
|
||||||
FGParkingRef m_selectedParking;
|
|
||||||
FGHelipadRef m_selectedHelipad;
|
|
||||||
|
|
||||||
QPainterPath m_helipadIconPath;
|
QPainterPath m_helipadIconPath;
|
||||||
|
FGPositionedRef m_selection;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // of GUI_AIRPORT_DIAGRAM_HXX
|
#endif // of GUI_AIRPORT_DIAGRAM_HXX
|
||||||
|
|
|
@ -26,6 +26,7 @@
|
||||||
#include <QDebug>
|
#include <QDebug>
|
||||||
#include <QVector2D>
|
#include <QVector2D>
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
|
#include <QPaintDevice>
|
||||||
|
|
||||||
#include <Navaids/navrecord.hxx>
|
#include <Navaids/navrecord.hxx>
|
||||||
#include <Navaids/positioned.hxx>
|
#include <Navaids/positioned.hxx>
|
||||||
|
@ -39,6 +40,7 @@ const double rec = 6378137; // earth radius, equator (?)
|
||||||
const double rpol = 6356752.314; // earth radius, polar (?)
|
const double rpol = 6356752.314; // earth radius, polar (?)
|
||||||
|
|
||||||
const double MINIMUM_SCALE = 0.002;
|
const double MINIMUM_SCALE = 0.002;
|
||||||
|
const double MAXIMUM_SCALE = 2.0;
|
||||||
|
|
||||||
//Returns Earth radius at a given latitude (Ellipsoide equation with two equal axis)
|
//Returns Earth radius at a given latitude (Ellipsoide equation with two equal axis)
|
||||||
static double earth_radius_lat( double lat )
|
static double earth_radius_lat( double lat )
|
||||||
|
@ -48,14 +50,15 @@ static double earth_radius_lat( double lat )
|
||||||
return 1.0 / sqrt( a * a + b * b );
|
return 1.0 / sqrt( a * a + b * b );
|
||||||
}
|
}
|
||||||
|
|
||||||
BaseDiagram::BaseDiagram(QWidget* pr) :
|
BaseDiagram::BaseDiagram(QQuickItem* pr) :
|
||||||
QWidget(pr),
|
QQuickPaintedItem(pr),
|
||||||
m_autoScalePan(true),
|
m_autoScalePan(true),
|
||||||
m_wheelAngleDeltaAccumulator(0)
|
m_wheelAngleDeltaAccumulator(0)
|
||||||
{
|
{
|
||||||
setSizePolicy(QSizePolicy::MinimumExpanding,
|
setAcceptedMouseButtons(Qt::LeftButton);
|
||||||
QSizePolicy::MinimumExpanding);
|
setFlag(ItemHasContents);
|
||||||
setMinimumSize(100, 100);
|
setOpaquePainting(true);
|
||||||
|
setAntialiasing(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
QTransform BaseDiagram::transform() const
|
QTransform BaseDiagram::transform() const
|
||||||
|
@ -98,11 +101,15 @@ void BaseDiagram::extendRect(QRectF &r, const QPointF &p)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseDiagram::paintEvent(QPaintEvent*)
|
QRect BaseDiagram::rect() const
|
||||||
{
|
{
|
||||||
QPainter p(this);
|
return QRect(0, 0, width(), height());
|
||||||
p.setRenderHints(QPainter::Antialiasing);
|
}
|
||||||
p.fillRect(rect(), QColor(0x3f, 0x3f, 0x3f));
|
|
||||||
|
void BaseDiagram::paint(QPainter* p)
|
||||||
|
{
|
||||||
|
//p->setRenderHints(QPainter::Antialiasing);
|
||||||
|
p->fillRect(rect(), QColor(0x3f, 0x3f, 0x3f));
|
||||||
|
|
||||||
if (m_autoScalePan) {
|
if (m_autoScalePan) {
|
||||||
// fit bounds within our available space, allowing for a margin
|
// fit bounds within our available space, allowing for a margin
|
||||||
|
@ -110,24 +117,26 @@ void BaseDiagram::paintEvent(QPaintEvent*)
|
||||||
double ratioInX = (width() - MARGIN * 2) / m_bounds.width();
|
double ratioInX = (width() - MARGIN * 2) / m_bounds.width();
|
||||||
double ratioInY = (height() - MARGIN * 2) / m_bounds.height();
|
double ratioInY = (height() - MARGIN * 2) / m_bounds.height();
|
||||||
m_scale = std::min(ratioInX, ratioInY);
|
m_scale = std::min(ratioInX, ratioInY);
|
||||||
|
SG_CLAMP_RANGE(m_scale, MINIMUM_SCALE, MAXIMUM_SCALE);
|
||||||
}
|
}
|
||||||
|
|
||||||
QTransform t(transform());
|
m_baseDeviceTransform = p->deviceTransform();
|
||||||
p.setTransform(t);
|
m_viewportTransform = transform();
|
||||||
|
p->setWorldTransform(m_viewportTransform * m_baseDeviceTransform);
|
||||||
|
|
||||||
paintPolygonData(&p);
|
paintPolygonData(p);
|
||||||
|
paintNavaids(p);
|
||||||
paintNavaids(&p);
|
paintContents(p);
|
||||||
|
|
||||||
paintContents(&p);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseDiagram::paintAirplaneIcon(QPainter* painter, const SGGeod& geod, int headingDeg)
|
void BaseDiagram::paintAirplaneIcon(QPainter* painter, const SGGeod& geod, int headingDeg)
|
||||||
{
|
{
|
||||||
QPointF pos = project(geod);
|
QPointF pos = project(geod);
|
||||||
QPixmap pix(":/airplane-icon");
|
QPixmap pix(":/airplane-icon");
|
||||||
pos = painter->transform().map(pos);
|
pos = m_viewportTransform.map(pos);
|
||||||
painter->resetTransform();
|
painter->save();
|
||||||
|
painter->setWorldTransform(m_baseDeviceTransform);
|
||||||
|
|
||||||
painter->translate(pos.x(), pos.y());
|
painter->translate(pos.x(), pos.y());
|
||||||
painter->rotate(headingDeg);
|
painter->rotate(headingDeg);
|
||||||
|
|
||||||
|
@ -135,16 +144,17 @@ void BaseDiagram::paintAirplaneIcon(QPainter* painter, const SGGeod& geod, int h
|
||||||
QRect airplaneIconRect = pix.rect();
|
QRect airplaneIconRect = pix.rect();
|
||||||
airplaneIconRect.moveCenter(QPoint(0,0));
|
airplaneIconRect.moveCenter(QPoint(0,0));
|
||||||
painter->drawPixmap(airplaneIconRect, pix);
|
painter->drawPixmap(airplaneIconRect, pix);
|
||||||
|
|
||||||
|
painter->restore();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseDiagram::paintPolygonData(QPainter* painter)
|
void BaseDiagram::paintPolygonData(QPainter* painter)
|
||||||
{
|
{
|
||||||
QTransform xf = painter->transform();
|
QTransform invT = m_viewportTransform.inverted();
|
||||||
QTransform invT = xf.inverted();
|
const auto geom = rect();
|
||||||
|
SGGeod topLeft = unproject(invT.map(geom.topLeft()), m_projectionCenter);
|
||||||
SGGeod topLeft = unproject(invT.map(rect().topLeft()), m_projectionCenter);
|
SGGeod viewCenter = unproject(invT.map(geom.center()), m_projectionCenter);
|
||||||
SGGeod viewCenter = unproject(invT.map(rect().center()), m_projectionCenter);
|
SGGeod bottomRight = unproject(invT.map(geom.bottomRight()), m_projectionCenter);
|
||||||
SGGeod bottomRight = unproject(invT.map(rect().bottomRight()), m_projectionCenter);
|
|
||||||
|
|
||||||
double drawRangeNm = std::max(SGGeodesy::distanceNm(viewCenter, topLeft),
|
double drawRangeNm = std::max(SGGeodesy::distanceNm(viewCenter, topLeft),
|
||||||
SGGeodesy::distanceNm(viewCenter, bottomRight));
|
SGGeodesy::distanceNm(viewCenter, bottomRight));
|
||||||
|
@ -155,35 +165,31 @@ void BaseDiagram::paintPolygonData(QPainter* painter)
|
||||||
QPen waterPen(QColor(64, 64, 255), 1);
|
QPen waterPen(QColor(64, 64, 255), 1);
|
||||||
waterPen.setCosmetic(true);
|
waterPen.setCosmetic(true);
|
||||||
painter->setPen(waterPen);
|
painter->setPen(waterPen);
|
||||||
flightgear::PolyLineList::const_iterator it;
|
for (auto line : lines) {
|
||||||
for (it=lines.begin(); it != lines.end(); ++it) {
|
paintGeodVec(painter, line->points());
|
||||||
paintGeodVec(painter, (*it)->points());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
lines = flightgear::PolyLine::linesNearPos(viewCenter, drawRangeNm,
|
lines = flightgear::PolyLine::linesNearPos(viewCenter, drawRangeNm,
|
||||||
flightgear::PolyLine::URBAN);
|
flightgear::PolyLine::URBAN);
|
||||||
for (it=lines.begin(); it != lines.end(); ++it) {
|
for (auto line : lines) {
|
||||||
fillClosedGeodVec(painter, QColor(192, 192, 96), (*it)->points());
|
fillClosedGeodVec(painter, QColor(192, 192, 96), line->points());
|
||||||
}
|
}
|
||||||
|
|
||||||
lines = flightgear::PolyLine::linesNearPos(viewCenter, drawRangeNm,
|
lines = flightgear::PolyLine::linesNearPos(viewCenter, drawRangeNm,
|
||||||
flightgear::PolyLine::RIVER);
|
flightgear::PolyLine::RIVER);
|
||||||
|
|
||||||
painter->setPen(waterPen);
|
painter->setPen(waterPen);
|
||||||
for (it=lines.begin(); it != lines.end(); ++it) {
|
for (auto line : lines) {
|
||||||
paintGeodVec(painter, (*it)->points());
|
paintGeodVec(painter, line->points());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
lines = flightgear::PolyLine::linesNearPos(viewCenter, drawRangeNm,
|
lines = flightgear::PolyLine::linesNearPos(viewCenter, drawRangeNm,
|
||||||
flightgear::PolyLine::LAKE);
|
flightgear::PolyLine::LAKE);
|
||||||
|
|
||||||
for (it=lines.begin(); it != lines.end(); ++it) {
|
for (auto line : lines) {
|
||||||
fillClosedGeodVec(painter, QColor(128, 128, 255),
|
fillClosedGeodVec(painter, QColor(128, 128, 255), line->points());
|
||||||
(*it)->points());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseDiagram::paintGeodVec(QPainter* painter, const flightgear::SGGeodVec& vec)
|
void BaseDiagram::paintGeodVec(QPainter* painter, const flightgear::SGGeodVec& vec)
|
||||||
|
@ -216,17 +222,17 @@ class MapFilter : public FGPositioned::TypeFilter
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
MapFilter(LauncherAircraftType aircraft)
|
MapFilter(LauncherController::AircraftType aircraft)
|
||||||
{
|
{
|
||||||
// addType(FGPositioned::FIX);
|
// addType(FGPositioned::FIX);
|
||||||
addType(FGPositioned::NDB);
|
addType(FGPositioned::NDB);
|
||||||
addType(FGPositioned::VOR);
|
addType(FGPositioned::VOR);
|
||||||
|
|
||||||
if (aircraft == Helicopter) {
|
if (aircraft == LauncherController::Helicopter) {
|
||||||
addType(FGPositioned::HELIPAD);
|
addType(FGPositioned::HELIPAD);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aircraft == Seaplane) {
|
if (aircraft == LauncherController::Seaplane) {
|
||||||
addType(FGPositioned::SEAPORT);
|
addType(FGPositioned::SEAPORT);
|
||||||
} else {
|
} else {
|
||||||
addType(FGPositioned::AIRPORT);
|
addType(FGPositioned::AIRPORT);
|
||||||
|
@ -252,12 +258,11 @@ public:
|
||||||
void BaseDiagram::splitItems(const FGPositionedList& in, FGPositionedList& navaids,
|
void BaseDiagram::splitItems(const FGPositionedList& in, FGPositionedList& navaids,
|
||||||
FGPositionedList& ports)
|
FGPositionedList& ports)
|
||||||
{
|
{
|
||||||
FGPositionedList::const_iterator it = in.begin();
|
for (auto p : in) {
|
||||||
for (; it != in.end(); ++it) {
|
if (FGPositioned::isAirportType(p)) {
|
||||||
if (FGPositioned::isAirportType(it->ptr())) {
|
ports.push_back(p);
|
||||||
ports.push_back(*it);
|
|
||||||
} else {
|
} else {
|
||||||
navaids.push_back(*it);
|
navaids.push_back(p);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -273,10 +278,8 @@ bool orderAirportsByRunwayLength(const FGPositionedRef& a,
|
||||||
|
|
||||||
void BaseDiagram::paintNavaids(QPainter* painter)
|
void BaseDiagram::paintNavaids(QPainter* painter)
|
||||||
{
|
{
|
||||||
QTransform xf = painter->transform();
|
painter->save();
|
||||||
painter->setTransform(QTransform()); // reset to identity
|
QTransform invT = m_viewportTransform.inverted();
|
||||||
QTransform invT = xf.inverted();
|
|
||||||
|
|
||||||
|
|
||||||
SGGeod topLeft = unproject(invT.map(rect().topLeft()), m_projectionCenter);
|
SGGeod topLeft = unproject(invT.map(rect().topLeft()), m_projectionCenter);
|
||||||
SGGeod viewCenter = unproject(invT.map(rect().center()), m_projectionCenter);
|
SGGeod viewCenter = unproject(invT.map(rect().center()), m_projectionCenter);
|
||||||
|
@ -300,19 +303,17 @@ void BaseDiagram::paintNavaids(QPainter* painter)
|
||||||
|
|
||||||
m_labelRects.clear();
|
m_labelRects.clear();
|
||||||
m_labelRects.reserve(items.size());
|
m_labelRects.reserve(items.size());
|
||||||
|
painter->setTransform(m_baseDeviceTransform);
|
||||||
|
|
||||||
FGPositionedList::const_iterator it;
|
for (auto port : ports) {
|
||||||
for (it = ports.begin(); it != ports.end(); ++it) {
|
paintNavaid(painter, port);
|
||||||
paintNavaid(painter, xf, *it);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (it = navaids.begin(); it != navaids.end(); ++it) {
|
for (auto nav : navaids) {
|
||||||
paintNavaid(painter, xf, *it);
|
paintNavaid(painter, nav);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
painter->restore();
|
||||||
// restore transform
|
|
||||||
painter->setTransform(xf);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
QRect boundsOfLines(const QVector<QLineF>& lines)
|
QRect boundsOfLines(const QVector<QLineF>& lines)
|
||||||
|
@ -325,7 +326,7 @@ QRect boundsOfLines(const QVector<QLineF>& lines)
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseDiagram::paintNavaid(QPainter* painter, const QTransform& t, const FGPositionedRef &pos)
|
void BaseDiagram::paintNavaid(QPainter* painter, const FGPositionedRef &pos)
|
||||||
{
|
{
|
||||||
if (isNavaidIgnored(pos))
|
if (isNavaidIgnored(pos))
|
||||||
return;
|
return;
|
||||||
|
@ -341,9 +342,11 @@ void BaseDiagram::paintNavaid(QPainter* painter, const QTransform& t, const FGPo
|
||||||
if (apt->hasHardRunwayOfLengthFt(minRunwayLengthFt)) {
|
if (apt->hasHardRunwayOfLengthFt(minRunwayLengthFt)) {
|
||||||
|
|
||||||
drawAsIcon = false;
|
drawAsIcon = false;
|
||||||
painter->setTransform(t);
|
|
||||||
QVector<QLineF> lines = projectAirportRuwaysWithCenter(apt, m_projectionCenter);
|
QVector<QLineF> lines = projectAirportRuwaysWithCenter(apt, m_projectionCenter);
|
||||||
|
|
||||||
|
painter->save();
|
||||||
|
painter->setTransform(m_viewportTransform * m_baseDeviceTransform);
|
||||||
|
|
||||||
QPen pen(QColor(0x03, 0x83, 0xbf), 8);
|
QPen pen(QColor(0x03, 0x83, 0xbf), 8);
|
||||||
pen.setCosmetic(true);
|
pen.setCosmetic(true);
|
||||||
painter->setPen(pen);
|
painter->setPen(pen);
|
||||||
|
@ -354,15 +357,15 @@ void BaseDiagram::paintNavaid(QPainter* painter, const QTransform& t, const FGPo
|
||||||
painter->setPen(linePen);
|
painter->setPen(linePen);
|
||||||
painter->drawLines(lines);
|
painter->drawLines(lines);
|
||||||
|
|
||||||
painter->resetTransform();
|
iconRect = m_viewportTransform.mapRect(boundsOfLines(lines));
|
||||||
|
|
||||||
iconRect = t.mapRect(boundsOfLines(lines));
|
painter->restore();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (drawAsIcon) {
|
if (drawAsIcon) {
|
||||||
QPixmap pm = iconForPositioned(pos);
|
QPixmap pm = iconForPositioned(pos);
|
||||||
QPointF loc = t.map(project(pos->geod()));
|
QPointF loc = m_viewportTransform.map(project(pos->geod()));
|
||||||
iconRect = pm.rect();
|
iconRect = pm.rect();
|
||||||
iconRect.moveCenter(loc.toPoint());
|
iconRect.moveCenter(loc.toPoint());
|
||||||
painter->drawPixmap(iconRect, pm);
|
painter->drawPixmap(iconRect, pm);
|
||||||
|
@ -510,8 +513,13 @@ QRect BaseDiagram::labelPositioned(const QRect& itemRect,
|
||||||
|
|
||||||
void BaseDiagram::mousePressEvent(QMouseEvent *me)
|
void BaseDiagram::mousePressEvent(QMouseEvent *me)
|
||||||
{
|
{
|
||||||
|
if (!hasActiveFocus()) {
|
||||||
|
forceActiveFocus(Qt::MouseFocusReason);
|
||||||
|
}
|
||||||
|
|
||||||
m_lastMousePos = me->pos();
|
m_lastMousePos = me->pos();
|
||||||
m_didPan = false;
|
m_didPan = false;
|
||||||
|
me->accept();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseDiagram::mouseMoveEvent(QMouseEvent *me)
|
void BaseDiagram::mouseMoveEvent(QMouseEvent *me)
|
||||||
|
@ -558,7 +566,7 @@ void BaseDiagram::wheelEvent(QWheelEvent *we)
|
||||||
m_scale *= 0.75;
|
m_scale *= 0.75;
|
||||||
}
|
}
|
||||||
|
|
||||||
SG_CLAMP_RANGE(m_scale, MINIMUM_SCALE, 1.0);
|
SG_CLAMP_RANGE(m_scale, MINIMUM_SCALE, MAXIMUM_SCALE);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -585,7 +593,7 @@ void BaseDiagram::doComputeBounds()
|
||||||
// no-op in the base class
|
// no-op in the base class
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseDiagram::extendBounds(const QPointF& p)
|
void BaseDiagram::extendBounds(const QPointF& p, double radiusM)
|
||||||
{
|
{
|
||||||
// this check added after a bug where apt.dat reports SCSL as
|
// this check added after a bug where apt.dat reports SCSL as
|
||||||
// https://airportguide.com/airport/info/AG0003 (British Columbia)
|
// https://airportguide.com/airport/info/AG0003 (British Columbia)
|
||||||
|
@ -598,7 +606,12 @@ void BaseDiagram::extendBounds(const QPointF& p)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (radiusM > 0.0) {
|
||||||
|
extendRect(m_bounds, p - QPointF(radiusM, radiusM));
|
||||||
|
extendRect(m_bounds, p + QPointF(radiusM, radiusM));
|
||||||
|
} else {
|
||||||
extendRect(m_bounds, p);
|
extendRect(m_bounds, p);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QPointF BaseDiagram::project(const SGGeod& geod, const SGGeod& center)
|
QPointF BaseDiagram::project(const SGGeod& geod, const SGGeod& center)
|
||||||
|
@ -787,7 +800,7 @@ QVector<QLineF> BaseDiagram::projectAirportRuwaysWithCenter(FGAirportRef apt, co
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BaseDiagram::setAircraftType(LauncherAircraftType type)
|
void BaseDiagram::setAircraftType(LauncherController::AircraftType type)
|
||||||
{
|
{
|
||||||
m_aircraftType = type;
|
m_aircraftType = type;
|
||||||
update();
|
update();
|
||||||
|
|
|
@ -21,23 +21,23 @@
|
||||||
#ifndef GUI_BASEDIAGRAM_HXX
|
#ifndef GUI_BASEDIAGRAM_HXX
|
||||||
#define GUI_BASEDIAGRAM_HXX
|
#define GUI_BASEDIAGRAM_HXX
|
||||||
|
|
||||||
#include <QWidget>
|
|
||||||
#include <QPainterPath>
|
#include <QPainterPath>
|
||||||
#include <QHash>
|
#include <QHash>
|
||||||
|
#include <QQuickPaintedItem>
|
||||||
|
#include <QTransform>
|
||||||
|
|
||||||
#include <simgear/math/sg_geodesy.hxx>
|
#include <simgear/math/sg_geodesy.hxx>
|
||||||
|
|
||||||
#include <Navaids/positioned.hxx>
|
#include <Navaids/positioned.hxx>
|
||||||
#include <Airports/airport.hxx>
|
#include <Airports/airport.hxx>
|
||||||
#include <Navaids/PolyLine.hxx>
|
#include <Navaids/PolyLine.hxx>
|
||||||
|
#include "LauncherController.hxx"
|
||||||
|
|
||||||
#include "QtLauncher_fwd.hxx"
|
class BaseDiagram : public QQuickPaintedItem
|
||||||
|
|
||||||
class BaseDiagram : public QWidget
|
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
public:
|
||||||
BaseDiagram(QWidget* pr);
|
BaseDiagram(QQuickItem* pr = nullptr);
|
||||||
|
|
||||||
enum IconOption
|
enum IconOption
|
||||||
{
|
{
|
||||||
|
@ -54,14 +54,16 @@ public:
|
||||||
static QVector<QLineF> projectAirportRuwaysIntoRect(FGAirportRef apt, const QRectF& bounds);
|
static QVector<QLineF> projectAirportRuwaysIntoRect(FGAirportRef apt, const QRectF& bounds);
|
||||||
static QVector<QLineF> projectAirportRuwaysWithCenter(FGAirportRef apt, const SGGeod &c);
|
static QVector<QLineF> projectAirportRuwaysWithCenter(FGAirportRef apt, const SGGeod &c);
|
||||||
|
|
||||||
void setAircraftType(LauncherAircraftType type);
|
void setAircraftType(LauncherController::AircraftType type);
|
||||||
|
|
||||||
|
QRect rect() const;
|
||||||
protected:
|
protected:
|
||||||
virtual void paintEvent(QPaintEvent* pe);
|
void paint(QPainter* p) override;
|
||||||
|
|
||||||
virtual void mousePressEvent(QMouseEvent* me);
|
void mousePressEvent(QMouseEvent* me) override;
|
||||||
virtual void mouseMoveEvent(QMouseEvent* me);
|
void mouseMoveEvent(QMouseEvent* me) override;
|
||||||
|
|
||||||
virtual void wheelEvent(QWheelEvent* we);
|
void wheelEvent(QWheelEvent* we) override;
|
||||||
|
|
||||||
virtual void paintContents(QPainter*);
|
virtual void paintContents(QPainter*);
|
||||||
|
|
||||||
|
@ -71,7 +73,7 @@ protected:
|
||||||
|
|
||||||
virtual void doComputeBounds();
|
virtual void doComputeBounds();
|
||||||
|
|
||||||
void extendBounds(const QPointF& p);
|
void extendBounds(const QPointF& p, double radiusM = 1.0);
|
||||||
QPointF project(const SGGeod& geod) const;
|
QPointF project(const SGGeod& geod) const;
|
||||||
QTransform transform() const;
|
QTransform transform() const;
|
||||||
|
|
||||||
|
@ -85,7 +87,7 @@ protected:
|
||||||
QPointF m_panOffset, m_lastMousePos;
|
QPointF m_panOffset, m_lastMousePos;
|
||||||
int m_wheelAngleDeltaAccumulator;
|
int m_wheelAngleDeltaAccumulator;
|
||||||
bool m_didPan;
|
bool m_didPan;
|
||||||
LauncherAircraftType m_aircraftType;
|
LauncherController::AircraftType m_aircraftType = LauncherController::Airplane;
|
||||||
|
|
||||||
static void extendRect(QRectF& r, const QPointF& p);
|
static void extendRect(QRectF& r, const QPointF& p);
|
||||||
|
|
||||||
|
@ -118,6 +120,8 @@ private:
|
||||||
int & flags /* out parameter */) const;
|
int & flags /* out parameter */) const;
|
||||||
QRect labelPositioned(const QRect &itemRect, const QSize &bounds, LabelPosition lp) const;
|
QRect labelPositioned(const QRect &itemRect, const QSize &bounds, LabelPosition lp) const;
|
||||||
|
|
||||||
|
QTransform m_baseDeviceTransform;
|
||||||
|
QTransform m_viewportTransform;
|
||||||
QVector<FGPositionedRef> m_ignored;
|
QVector<FGPositionedRef> m_ignored;
|
||||||
|
|
||||||
mutable QHash<PositionedID, LabelPosition> m_labelPositions;
|
mutable QHash<PositionedID, LabelPosition> m_labelPositions;
|
||||||
|
@ -126,9 +130,7 @@ private:
|
||||||
static int textFlagsForLabelPosition(LabelPosition pos);
|
static int textFlagsForLabelPosition(LabelPosition pos);
|
||||||
|
|
||||||
void splitItems(const FGPositionedList &in, FGPositionedList &navaids, FGPositionedList &ports);
|
void splitItems(const FGPositionedList &in, FGPositionedList &navaids, FGPositionedList &ports);
|
||||||
void paintNavaid(QPainter *painter,
|
void paintNavaid(QPainter *painter, const FGPositionedRef &pos);
|
||||||
const QTransform& t,
|
|
||||||
const FGPositionedRef &pos);
|
|
||||||
void paintPolygonData(QPainter *painter);
|
void paintPolygonData(QPainter *painter);
|
||||||
void paintGeodVec(QPainter *painter, const flightgear::SGGeodVec &vec);
|
void paintGeodVec(QPainter *painter, const flightgear::SGGeodVec &vec);
|
||||||
void fillClosedGeodVec(QPainter *painter, const QColor &color, const flightgear::SGGeodVec &vec);
|
void fillClosedGeodVec(QPainter *painter, const QColor &color, const flightgear::SGGeodVec &vec);
|
||||||
|
|
|
@ -69,7 +69,6 @@ endif()
|
||||||
if (HAVE_QT)
|
if (HAVE_QT)
|
||||||
qt5_wrap_ui(uic_sources Launcher.ui
|
qt5_wrap_ui(uic_sources Launcher.ui
|
||||||
SetupRootDialog.ui
|
SetupRootDialog.ui
|
||||||
LocationWidget.ui
|
|
||||||
InstallSceneryDialog.ui
|
InstallSceneryDialog.ui
|
||||||
)
|
)
|
||||||
qt5_add_resources(qrc_sources resources.qrc)
|
qt5_add_resources(qrc_sources resources.qrc)
|
||||||
|
@ -90,14 +89,14 @@ if (HAVE_QT)
|
||||||
AircraftModel.cxx
|
AircraftModel.cxx
|
||||||
CatalogListModel.cxx
|
CatalogListModel.cxx
|
||||||
CatalogListModel.hxx
|
CatalogListModel.hxx
|
||||||
LocationWidget.cxx
|
|
||||||
LocationWidget.hxx
|
|
||||||
QtMessageBox.cxx
|
QtMessageBox.cxx
|
||||||
QtMessageBox.hxx
|
QtMessageBox.hxx
|
||||||
QtFileDialog.cxx
|
QtFileDialog.cxx
|
||||||
QtFileDialog.hxx
|
QtFileDialog.hxx
|
||||||
InstallSceneryDialog.hxx
|
InstallSceneryDialog.hxx
|
||||||
InstallSceneryDialog.cxx
|
InstallSceneryDialog.cxx
|
||||||
|
LocationController.cxx
|
||||||
|
LocationController.hxx
|
||||||
ToolboxButton.cpp
|
ToolboxButton.cpp
|
||||||
ToolboxButton.h
|
ToolboxButton.h
|
||||||
LauncherArgumentTokenizer.cxx
|
LauncherArgumentTokenizer.cxx
|
||||||
|
@ -122,6 +121,8 @@ if (HAVE_QT)
|
||||||
LauncherController.hxx
|
LauncherController.hxx
|
||||||
AddOnsController.cxx
|
AddOnsController.cxx
|
||||||
AddOnsController.hxx
|
AddOnsController.hxx
|
||||||
|
PixmapImageItem.cxx
|
||||||
|
PixmapImageItem.hxx
|
||||||
${uic_sources}
|
${uic_sources}
|
||||||
${qrc_sources}
|
${qrc_sources}
|
||||||
${qml_sources})
|
${qml_sources})
|
||||||
|
@ -150,6 +151,12 @@ if (HAVE_QT)
|
||||||
ThumbnailImageItem.hxx
|
ThumbnailImageItem.hxx
|
||||||
PopupWindowTracker.cxx
|
PopupWindowTracker.cxx
|
||||||
PopupWindowTracker.hxx
|
PopupWindowTracker.hxx
|
||||||
|
QmlPositioned.hxx
|
||||||
|
QmlPositioned.cxx
|
||||||
|
QmlNavCacheWrapper.hxx
|
||||||
|
QmlNavCacheWrapper.cxx
|
||||||
|
QmlRadioButtonHelper.cxx
|
||||||
|
QmlRadioButtonHelper.hxx
|
||||||
)
|
)
|
||||||
|
|
||||||
set_property(TARGET fgqmlui PROPERTY AUTOMOC ON)
|
set_property(TARGET fgqmlui PROPERTY AUTOMOC ON)
|
||||||
|
|
|
@ -299,7 +299,9 @@
|
||||||
</widget>
|
</widget>
|
||||||
|
|
||||||
|
|
||||||
<widget class="LocationWidget" name="location"/>
|
<widget class="QQuickWidget" name="location">
|
||||||
|
|
||||||
|
</widget>
|
||||||
|
|
||||||
<widget class="QQuickWidget" name="environmentPage">
|
<widget class="QQuickWidget" name="environmentPage">
|
||||||
</widget>
|
</widget>
|
||||||
|
@ -360,12 +362,6 @@
|
||||||
<extends>QWidget</extends>
|
<extends>QWidget</extends>
|
||||||
<header>QtQuickWidgets/QQuickWidget</header>
|
<header>QtQuickWidgets/QQuickWidget</header>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
<customwidget>
|
|
||||||
<class>LocationWidget</class>
|
|
||||||
<extends>QWidget</extends>
|
|
||||||
<header location="global">GUI/LocationWidget.hxx</header>
|
|
||||||
<container>1</container>
|
|
||||||
</customwidget>
|
|
||||||
<customwidget>
|
<customwidget>
|
||||||
<class>ToolboxButton</class>
|
<class>ToolboxButton</class>
|
||||||
<extends>QPushButton</extends>
|
<extends>QPushButton</extends>
|
||||||
|
|
|
@ -9,6 +9,7 @@
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QSettings>
|
#include <QSettings>
|
||||||
#include <QQuickWindow>
|
#include <QQuickWindow>
|
||||||
|
#include <QQmlComponent>
|
||||||
|
|
||||||
// simgear headers
|
// simgear headers
|
||||||
#include <simgear/package/Install.hxx>
|
#include <simgear/package/Install.hxx>
|
||||||
|
@ -38,26 +39,29 @@
|
||||||
#include "DefaultAircraftLocator.hxx"
|
#include "DefaultAircraftLocator.hxx"
|
||||||
#include "LaunchConfig.hxx"
|
#include "LaunchConfig.hxx"
|
||||||
#include "AircraftModel.hxx"
|
#include "AircraftModel.hxx"
|
||||||
|
#include "LocationController.hxx"
|
||||||
// remove me once location widget is ported to Quick
|
#include "QmlPositioned.hxx"
|
||||||
#include "LocationWidget.hxx"
|
#include "PixmapImageItem.hxx"
|
||||||
|
#include "AirportDiagram.hxx"
|
||||||
|
#include "NavaidDiagram.hxx"
|
||||||
|
#include "QmlRadioButtonHelper.hxx"
|
||||||
|
|
||||||
using namespace simgear::pkg;
|
using namespace simgear::pkg;
|
||||||
|
|
||||||
|
|
||||||
LauncherController::LauncherController(QObject *parent,
|
LauncherController::LauncherController(QObject *parent) :
|
||||||
LocationWidget* loc) :
|
QObject(parent)
|
||||||
QObject(parent),
|
|
||||||
m_locationWidget_FIXME(loc)
|
|
||||||
{
|
{
|
||||||
m_serversModel = new MPServersModel(this);
|
m_serversModel = new MPServersModel(this);
|
||||||
|
m_location = new LocationController(this);
|
||||||
m_locationHistory = new RecentLocationsModel(this);
|
m_locationHistory = new RecentLocationsModel(this);
|
||||||
m_selectedAircraftInfo = new QmlAircraftInfo(this);
|
m_selectedAircraftInfo = new QmlAircraftInfo(this);
|
||||||
|
|
||||||
m_config = new LaunchConfig(this);
|
m_config = new LaunchConfig(this);
|
||||||
connect(m_config, &LaunchConfig::collect, this, &LauncherController::collectAircraftArgs);
|
connect(m_config, &LaunchConfig::collect, this, &LauncherController::collectAircraftArgs);
|
||||||
|
|
||||||
connect(m_locationWidget_FIXME, &LocationWidget::descriptionChanged,
|
m_location->setLaunchConfig(m_config);
|
||||||
|
connect(m_location, &LocationController::descriptionChanged,
|
||||||
this, &LauncherController::summaryChanged);
|
this, &LauncherController::summaryChanged);
|
||||||
|
|
||||||
initQML();
|
initQML();
|
||||||
|
@ -91,6 +95,9 @@ LauncherController::LauncherController(QObject *parent,
|
||||||
|
|
||||||
void LauncherController::initQML()
|
void LauncherController::initQML()
|
||||||
{
|
{
|
||||||
|
qmlRegisterUncreatableType<LauncherController>("FlightGear.Launcher", 1, 0, "LauncherController", "no");
|
||||||
|
qmlRegisterUncreatableType<LocationController>("FlightGear.Launcher", 1, 0, "LocationController", "no");
|
||||||
|
|
||||||
qmlRegisterType<LauncherArgumentTokenizer>("FlightGear.Launcher", 1, 0, "ArgumentTokenizer");
|
qmlRegisterType<LauncherArgumentTokenizer>("FlightGear.Launcher", 1, 0, "ArgumentTokenizer");
|
||||||
qmlRegisterUncreatableType<QAbstractItemModel>("FlightGear.Launcher", 1, 0, "QAIM", "no");
|
qmlRegisterUncreatableType<QAbstractItemModel>("FlightGear.Launcher", 1, 0, "QAIM", "no");
|
||||||
qmlRegisterUncreatableType<AircraftProxyModel>("FlightGear.Launcher", 1, 0, "AircraftProxyModel", "no");
|
qmlRegisterUncreatableType<AircraftProxyModel>("FlightGear.Launcher", 1, 0, "AircraftProxyModel", "no");
|
||||||
|
@ -108,6 +115,15 @@ void LauncherController::initQML()
|
||||||
qmlRegisterType<ThumbnailImageItem>("FlightGear.Launcher", 1, 0, "ThumbnailImage");
|
qmlRegisterType<ThumbnailImageItem>("FlightGear.Launcher", 1, 0, "ThumbnailImage");
|
||||||
qmlRegisterType<PreviewImageItem>("FlightGear.Launcher", 1, 0, "PreviewImage");
|
qmlRegisterType<PreviewImageItem>("FlightGear.Launcher", 1, 0, "PreviewImage");
|
||||||
|
|
||||||
|
qmlRegisterType<QmlPositioned>("FlightGear", 1, 0, "Positioned");
|
||||||
|
// this is a Q_GADGET, but we need to register it for use in return types, etc
|
||||||
|
qRegisterMetaType<QmlGeod>();
|
||||||
|
|
||||||
|
qmlRegisterType<PixmapImageItem>("FlightGear", 1, 0, "PixmapImage");
|
||||||
|
qmlRegisterType<AirportDiagram>("FlightGear", 1, 0, "AirportDiagram");
|
||||||
|
qmlRegisterType<NavaidDiagram>("FlightGear", 1, 0, "NavaidDiagram");
|
||||||
|
qmlRegisterType<QmlRadioButtonGroup>("FlightGear", 1, 0, "RadioButtonGroup");
|
||||||
|
|
||||||
QNetworkDiskCache* diskCache = new QNetworkDiskCache(this);
|
QNetworkDiskCache* diskCache = new QNetworkDiskCache(this);
|
||||||
SGPath cachePath = globals->get_fg_home() / "PreviewsCache";
|
SGPath cachePath = globals->get_fg_home() / "PreviewsCache";
|
||||||
diskCache->setCacheDirectory(QString::fromStdString(cachePath.utf8Str()));
|
diskCache->setCacheDirectory(QString::fromStdString(cachePath.utf8Str()));
|
||||||
|
@ -132,7 +148,7 @@ void LauncherController::restoreSettings()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
m_locationWidget_FIXME->restoreSettings();
|
m_location->restoreSettings();
|
||||||
QVariantMap currentLocation = m_locationHistory->mostRecent();
|
QVariantMap currentLocation = m_locationHistory->mostRecent();
|
||||||
if (currentLocation.isEmpty()) {
|
if (currentLocation.isEmpty()) {
|
||||||
// use the default
|
// use the default
|
||||||
|
@ -143,7 +159,7 @@ void LauncherController::restoreSettings()
|
||||||
currentLocation["location-apt-runway"] = "active";
|
currentLocation["location-apt-runway"] = "active";
|
||||||
} // otherwise we failed to find the default airport in the nav-db :(
|
} // otherwise we failed to find the default airport in the nav-db :(
|
||||||
}
|
}
|
||||||
m_locationWidget_FIXME->restoreLocation(currentLocation);
|
m_location->restoreLocation(currentLocation);
|
||||||
|
|
||||||
updateSelectedAircraft();
|
updateSelectedAircraft();
|
||||||
m_serversModel->requestRestore();
|
m_serversModel->requestRestore();
|
||||||
|
@ -199,7 +215,7 @@ void LauncherController::doRun()
|
||||||
|
|
||||||
m_aircraftHistory->insert(m_selectedAircraft);
|
m_aircraftHistory->insert(m_selectedAircraft);
|
||||||
|
|
||||||
QVariant locSet = m_locationWidget_FIXME->saveLocation();
|
QVariant locSet = m_location->saveLocation();
|
||||||
m_locationHistory->insert(locSet);
|
m_locationHistory->insert(locSet);
|
||||||
|
|
||||||
// aircraft paths
|
// aircraft paths
|
||||||
|
@ -257,8 +273,7 @@ void LauncherController::doApply()
|
||||||
globals->get_props()->setStringValue("/sim/aircraft-dir", aircraftDir);
|
globals->get_props()->setStringValue("/sim/aircraft-dir", aircraftDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
// location
|
m_location->setLocationProperties();
|
||||||
m_locationWidget_FIXME->setLocationProperties();
|
|
||||||
saveSettings();
|
saveSettings();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -268,13 +283,12 @@ QString LauncherController::selectAircraftStateAutomatically()
|
||||||
if (!m_selectedAircraftInfo)
|
if (!m_selectedAircraftInfo)
|
||||||
return {};
|
return {};
|
||||||
|
|
||||||
if (m_locationWidget_FIXME->isAirborneLocation()) {
|
if (m_location->isAirborneLocation() && m_selectedAircraftInfo->hasState("approach"))
|
||||||
if (m_selectedAircraftInfo->hasState("approach"))
|
{
|
||||||
return "approach";
|
return "approach";
|
||||||
}
|
}
|
||||||
|
|
||||||
if (m_locationWidget_FIXME->isParkedLocation()) {
|
if (m_location->isParkedLocation() && m_selectedAircraftInfo->hasState("parked")) {
|
||||||
if (m_selectedAircraftInfo->hasState("parked"))
|
|
||||||
return "parked";
|
return "parked";
|
||||||
} else {
|
} else {
|
||||||
// also try 'engines-running'?
|
// also try 'engines-running'?
|
||||||
|
@ -299,14 +313,12 @@ void LauncherController::updateSelectedAircraft()
|
||||||
m_selectedAircraftInfo->setUri(m_selectedAircraft);
|
m_selectedAircraftInfo->setUri(m_selectedAircraft);
|
||||||
QModelIndex index = m_aircraftModel->indexOfAircraftURI(m_selectedAircraft);
|
QModelIndex index = m_aircraftModel->indexOfAircraftURI(m_selectedAircraft);
|
||||||
if (index.isValid()) {
|
if (index.isValid()) {
|
||||||
LauncherAircraftType aircraftType = Airplane;
|
m_aircraftType = Airplane;
|
||||||
if (index.data(AircraftIsHelicopterRole).toBool()) {
|
if (index.data(AircraftIsHelicopterRole).toBool()) {
|
||||||
aircraftType = Helicopter;
|
m_aircraftType = Helicopter;
|
||||||
} else if (index.data(AircraftIsSeaplaneRole).toBool()) {
|
} else if (index.data(AircraftIsSeaplaneRole).toBool()) {
|
||||||
aircraftType = Seaplane;
|
m_aircraftType = Seaplane;
|
||||||
}
|
}
|
||||||
|
|
||||||
m_locationWidget_FIXME->setAircraftType(aircraftType);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
emit canFlyChanged();
|
emit canFlyChanged();
|
||||||
|
@ -380,10 +392,9 @@ QmlAircraftInfo *LauncherController::selectedAircraftInfo() const
|
||||||
|
|
||||||
void LauncherController::restoreLocation(QVariant var)
|
void LauncherController::restoreLocation(QVariant var)
|
||||||
{
|
{
|
||||||
m_locationWidget_FIXME->restoreLocation(var.toMap());
|
m_location->restoreLocation(var.toMap());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
QUrl LauncherController::selectedAircraft() const
|
QUrl LauncherController::selectedAircraft() const
|
||||||
{
|
{
|
||||||
return m_selectedAircraft;
|
return m_selectedAircraft;
|
||||||
|
@ -458,11 +469,6 @@ QStringList LauncherController::combinedSummary() const
|
||||||
return m_settingsSummary + m_environmentSummary;
|
return m_settingsSummary + m_environmentSummary;
|
||||||
}
|
}
|
||||||
|
|
||||||
QString LauncherController::locationDescription() const
|
|
||||||
{
|
|
||||||
return m_locationWidget_FIXME->locationDescription();
|
|
||||||
}
|
|
||||||
|
|
||||||
simgear::pkg::PackageRef LauncherController::packageForAircraftURI(QUrl uri) const
|
simgear::pkg::PackageRef LauncherController::packageForAircraftURI(QUrl uri) const
|
||||||
{
|
{
|
||||||
if (uri.scheme() != "package") {
|
if (uri.scheme() != "package") {
|
||||||
|
|
|
@ -35,9 +35,9 @@ class RecentAircraftModel;
|
||||||
class RecentLocationsModel;
|
class RecentLocationsModel;
|
||||||
class MPServersModel;
|
class MPServersModel;
|
||||||
class AircraftItemModel;
|
class AircraftItemModel;
|
||||||
class LocationWidget;
|
|
||||||
class QQuickItem;
|
class QQuickItem;
|
||||||
class LaunchConfig;
|
class LaunchConfig;
|
||||||
|
class LocationController;
|
||||||
|
|
||||||
class LauncherController : public QObject
|
class LauncherController : public QObject
|
||||||
{
|
{
|
||||||
|
@ -49,6 +49,8 @@ class LauncherController : public QObject
|
||||||
|
|
||||||
Q_PROPERTY(AircraftItemModel* baseAircraftModel MEMBER m_aircraftModel CONSTANT)
|
Q_PROPERTY(AircraftItemModel* baseAircraftModel MEMBER m_aircraftModel CONSTANT)
|
||||||
|
|
||||||
|
Q_PROPERTY(LocationController* location MEMBER m_location CONSTANT)
|
||||||
|
|
||||||
Q_PROPERTY(MPServersModel* mpServersModel MEMBER m_serversModel CONSTANT)
|
Q_PROPERTY(MPServersModel* mpServersModel MEMBER m_serversModel CONSTANT)
|
||||||
|
|
||||||
Q_PROPERTY(QUrl selectedAircraft READ selectedAircraft WRITE setSelectedAircraft NOTIFY selectedAircraftChanged)
|
Q_PROPERTY(QUrl selectedAircraft READ selectedAircraft WRITE setSelectedAircraft NOTIFY selectedAircraftChanged)
|
||||||
|
@ -61,7 +63,6 @@ class LauncherController : public QObject
|
||||||
Q_PROPERTY(QStringList settingsSummary READ settingsSummary WRITE setSettingsSummary NOTIFY summaryChanged)
|
Q_PROPERTY(QStringList settingsSummary READ settingsSummary WRITE setSettingsSummary NOTIFY summaryChanged)
|
||||||
Q_PROPERTY(QStringList environmentSummary READ environmentSummary WRITE setEnvironmentSummary NOTIFY summaryChanged)
|
Q_PROPERTY(QStringList environmentSummary READ environmentSummary WRITE setEnvironmentSummary NOTIFY summaryChanged)
|
||||||
|
|
||||||
Q_PROPERTY(QString locationDescription READ locationDescription NOTIFY summaryChanged)
|
|
||||||
Q_PROPERTY(QStringList combinedSummary READ combinedSummary NOTIFY summaryChanged)
|
Q_PROPERTY(QStringList combinedSummary READ combinedSummary NOTIFY summaryChanged)
|
||||||
|
|
||||||
Q_PROPERTY(QString versionString READ versionString CONSTANT)
|
Q_PROPERTY(QString versionString READ versionString CONSTANT)
|
||||||
|
@ -70,9 +71,10 @@ class LauncherController : public QObject
|
||||||
Q_PROPERTY(RecentLocationsModel* locationHistory READ locationHistory CONSTANT)
|
Q_PROPERTY(RecentLocationsModel* locationHistory READ locationHistory CONSTANT)
|
||||||
|
|
||||||
Q_PROPERTY(bool canFly READ canFly NOTIFY canFlyChanged)
|
Q_PROPERTY(bool canFly READ canFly NOTIFY canFlyChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(AircraftType aircraftType READ aircraftType NOTIFY selectedAircraftChanged)
|
||||||
public:
|
public:
|
||||||
explicit LauncherController(QObject *parent,
|
explicit LauncherController(QObject *parent);
|
||||||
LocationWidget* loc);
|
|
||||||
|
|
||||||
void initQML();
|
void initQML();
|
||||||
|
|
||||||
|
@ -114,8 +116,6 @@ public:
|
||||||
|
|
||||||
QStringList combinedSummary() const;
|
QStringList combinedSummary() const;
|
||||||
|
|
||||||
QString locationDescription() const;
|
|
||||||
|
|
||||||
QString versionString() const;
|
QString versionString() const;
|
||||||
|
|
||||||
RecentAircraftModel* aircraftHistory();
|
RecentAircraftModel* aircraftHistory();
|
||||||
|
@ -144,6 +144,22 @@ public:
|
||||||
|
|
||||||
void restoreSettings();
|
void restoreSettings();
|
||||||
void saveSettings();
|
void saveSettings();
|
||||||
|
|
||||||
|
LocationController* location() const
|
||||||
|
{ return m_location; }
|
||||||
|
|
||||||
|
enum AircraftType
|
||||||
|
{
|
||||||
|
Airplane = 0,
|
||||||
|
Seaplane,
|
||||||
|
Helicopter,
|
||||||
|
Airship
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_ENUM(AircraftType)
|
||||||
|
|
||||||
|
AircraftType aircraftType() const
|
||||||
|
{ return m_aircraftType; }
|
||||||
signals:
|
signals:
|
||||||
|
|
||||||
void selectedAircraftChanged(QUrl selectedAircraft);
|
void selectedAircraftChanged(QUrl selectedAircraft);
|
||||||
|
@ -195,8 +211,10 @@ private:
|
||||||
AircraftProxyModel* m_aircraftSearchModel;
|
AircraftProxyModel* m_aircraftSearchModel;
|
||||||
AircraftProxyModel* m_browseAircraftModel;
|
AircraftProxyModel* m_browseAircraftModel;
|
||||||
MPServersModel* m_serversModel = nullptr;
|
MPServersModel* m_serversModel = nullptr;
|
||||||
|
LocationController* m_location = nullptr;
|
||||||
|
|
||||||
QUrl m_selectedAircraft;
|
QUrl m_selectedAircraft;
|
||||||
|
AircraftType m_aircraftType = Airplane;
|
||||||
int m_ratingFilters[4] = {3, 3, 3, 3};
|
int m_ratingFilters[4] = {3, 3, 3, 3};
|
||||||
LaunchConfig* m_config = nullptr;
|
LaunchConfig* m_config = nullptr;
|
||||||
QmlAircraftInfo* m_selectedAircraftInfo = nullptr;
|
QmlAircraftInfo* m_selectedAircraftInfo = nullptr;
|
||||||
|
@ -204,8 +222,6 @@ private:
|
||||||
QStringList m_settingsSummary, m_environmentSummary;
|
QStringList m_settingsSummary, m_environmentSummary;
|
||||||
RecentAircraftModel* m_aircraftHistory = nullptr;
|
RecentAircraftModel* m_aircraftHistory = nullptr;
|
||||||
RecentLocationsModel* m_locationHistory = nullptr;
|
RecentLocationsModel* m_locationHistory = nullptr;
|
||||||
|
|
||||||
LocationWidget* m_locationWidget_FIXME = nullptr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // LAUNCHERCONTROLLER_HXX
|
#endif // LAUNCHERCONTROLLER_HXX
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
#include "DefaultAircraftLocator.hxx"
|
#include "DefaultAircraftLocator.hxx"
|
||||||
#include "AddOnsController.hxx"
|
#include "AddOnsController.hxx"
|
||||||
#include "CatalogListModel.hxx"
|
#include "CatalogListModel.hxx"
|
||||||
|
#include "LocationController.hxx"
|
||||||
|
|
||||||
#include "ui_Launcher.h"
|
#include "ui_Launcher.h"
|
||||||
|
|
||||||
|
@ -69,14 +70,12 @@ LauncherMainWindow::LauncherMainWindow() :
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
m_controller = new LauncherController(this, m_ui->location);
|
m_controller = new LauncherController(this);
|
||||||
m_controller->initQML();
|
m_controller->initQML();
|
||||||
|
|
||||||
connect(m_controller, &LauncherController::canFlyChanged,
|
connect(m_controller, &LauncherController::canFlyChanged,
|
||||||
this, &LauncherMainWindow::onCanFlyChanged);
|
this, &LauncherMainWindow::onCanFlyChanged);
|
||||||
|
|
||||||
m_ui->location->setLaunchConfig(m_controller->config());
|
|
||||||
|
|
||||||
QMenu* toolsMenu = mb->addMenu(tr("Tools"));
|
QMenu* toolsMenu = mb->addMenu(tr("Tools"));
|
||||||
QAction* restoreDefaultsAction = toolsMenu->addAction(tr("Restore defaults..."));
|
QAction* restoreDefaultsAction = toolsMenu->addAction(tr("Restore defaults..."));
|
||||||
connect(restoreDefaultsAction, &QAction::triggered,
|
connect(restoreDefaultsAction, &QAction::triggered,
|
||||||
|
@ -143,6 +142,18 @@ LauncherMainWindow::LauncherMainWindow() :
|
||||||
this, &LauncherMainWindow::onQuickStatusChanged);
|
this, &LauncherMainWindow::onQuickStatusChanged);
|
||||||
m_ui->aircraftList->setSource(QUrl("qrc:///qml/AircraftList.qml"));
|
m_ui->aircraftList->setSource(QUrl("qrc:///qml/AircraftList.qml"));
|
||||||
|
|
||||||
|
/////////////
|
||||||
|
// location
|
||||||
|
m_ui->location->setResizeMode(QQuickWidget::SizeRootObjectToView);
|
||||||
|
m_ui->location->engine()->addImportPath("qrc:///");
|
||||||
|
m_ui->location->engine()->rootContext()->setContextProperty("_launcher", m_controller);
|
||||||
|
m_ui->location->engine()->rootContext()->setContextProperty("_config", m_controller->config());
|
||||||
|
m_ui->location->engine()->rootContext()->setContextProperty("_location", m_controller->location());
|
||||||
|
connect( m_ui->location, &QQuickWidget::statusChanged,
|
||||||
|
this, &LauncherMainWindow::onQuickStatusChanged);
|
||||||
|
m_ui->location->setSource(QUrl("qrc:///qml/Location.qml"));
|
||||||
|
|
||||||
|
/////////////
|
||||||
// settings
|
// settings
|
||||||
m_ui->settings->engine()->addImportPath("qrc:///");
|
m_ui->settings->engine()->addImportPath("qrc:///");
|
||||||
QQmlContext* settingsContext = m_ui->settings->engine()->rootContext();
|
QQmlContext* settingsContext = m_ui->settings->engine()->rootContext();
|
||||||
|
|
1116
src/GUI/LocationController.cxx
Normal file
1116
src/GUI/LocationController.cxx
Normal file
File diff suppressed because it is too large
Load diff
203
src/GUI/LocationController.hxx
Normal file
203
src/GUI/LocationController.hxx
Normal file
|
@ -0,0 +1,203 @@
|
||||||
|
// LocationController.hxx - GUI launcher dialog using Qt5
|
||||||
|
//
|
||||||
|
// Written by James Turner, started October 2015.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2015 James Turner <zakalawe@mac.com>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#ifndef LOCATION_CONTROLLER_HXX
|
||||||
|
#define LOCATION_CONTROLLER_HXX
|
||||||
|
|
||||||
|
#include <QObjectList>
|
||||||
|
|
||||||
|
#include <Navaids/positioned.hxx>
|
||||||
|
#include <Airports/airports_fwd.hxx>
|
||||||
|
|
||||||
|
#include "QtLauncher_fwd.hxx"
|
||||||
|
#include "LaunchConfig.hxx"
|
||||||
|
#include "QmlPositioned.hxx"
|
||||||
|
|
||||||
|
class NavSearchModel;
|
||||||
|
|
||||||
|
class LocationController : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PROPERTY(QString description READ description NOTIFY descriptionChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(NavSearchModel* searchModel MEMBER m_searchModel CONSTANT)
|
||||||
|
|
||||||
|
Q_PROPERTY(QList<QObject*> airportRunways READ airportRunways NOTIFY baseLocationChanged)
|
||||||
|
Q_PROPERTY(QList<QObject*> airportParkings READ airportParkings NOTIFY baseLocationChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(bool offsetEnabled READ offsetEnabled WRITE setOffsetEnabled NOTIFY offsetChanged)
|
||||||
|
Q_PROPERTY(int offsetRadial READ offsetRadial WRITE setOffsetRadial NOTIFY offsetChanged)
|
||||||
|
Q_PROPERTY(bool offsetBearingIsTrue MEMBER m_offsetBearingIsTrue NOTIFY offsetChanged)
|
||||||
|
Q_PROPERTY(double offsetNm READ offsetNm WRITE setOffsetNm NOTIFY offsetChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(int headingDeg MEMBER m_headingDeg NOTIFY configChanged)
|
||||||
|
Q_PROPERTY(int altitudeFt MEMBER m_altitudeFt NOTIFY configChanged)
|
||||||
|
Q_PROPERTY(int airspeedKnots MEMBER m_airspeedKnots NOTIFY configChanged)
|
||||||
|
Q_PROPERTY(bool onFinal READ onFinal WRITE setOnFinal NOTIFY configChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(bool isAirportLocation READ isAirportLocation NOTIFY baseLocationChanged)
|
||||||
|
Q_PROPERTY(bool useActiveRunway READ useActiveRunway WRITE setUseActiveRunway NOTIFY configChanged)
|
||||||
|
Q_PROPERTY(bool useAvailableParking READ useAvailableParking WRITE setUseAvailableParking NOTIFY configChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(bool tuneNAV1 READ tuneNAV1 WRITE setTuneNAV1 NOTIFY configChanged)
|
||||||
|
Q_PROPERTY(QmlGeod baseGeod READ baseGeod WRITE setBaseGeod NOTIFY baseLocationChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(QmlPositioned* detail READ detail CONSTANT)
|
||||||
|
public:
|
||||||
|
explicit LocationController(QObject *parent = nullptr);
|
||||||
|
~LocationController();
|
||||||
|
|
||||||
|
void setLaunchConfig(LaunchConfig* config);
|
||||||
|
|
||||||
|
QString description() const;
|
||||||
|
|
||||||
|
void setBaseLocation(FGPositionedRef ref);
|
||||||
|
|
||||||
|
bool shouldStartPaused() const;
|
||||||
|
|
||||||
|
void setLocationProperties();
|
||||||
|
|
||||||
|
void restoreLocation(QVariantMap l);
|
||||||
|
QVariantMap saveLocation() const;
|
||||||
|
|
||||||
|
void restoreSettings();
|
||||||
|
|
||||||
|
/// used to automatically select aircraft state
|
||||||
|
bool isParkedLocation() const;
|
||||||
|
|
||||||
|
/// used to automatically select aircraft state
|
||||||
|
bool isAirborneLocation() const;
|
||||||
|
|
||||||
|
int offsetRadial() const;
|
||||||
|
|
||||||
|
double offsetNm() const
|
||||||
|
{
|
||||||
|
return m_offsetNm;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_INVOKABLE void setBaseLocation(QmlPositioned* pos);
|
||||||
|
|
||||||
|
Q_INVOKABLE void setDetailLocation(QmlPositioned* pos);
|
||||||
|
|
||||||
|
QmlGeod baseGeod() const;
|
||||||
|
void setBaseGeod(QmlGeod geod);
|
||||||
|
|
||||||
|
bool isAirportLocation() const;
|
||||||
|
|
||||||
|
bool offsetEnabled() const
|
||||||
|
{
|
||||||
|
return m_offsetEnabled;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool onFinal() const
|
||||||
|
{
|
||||||
|
return m_onFinal;
|
||||||
|
}
|
||||||
|
|
||||||
|
void setUseActiveRunway(bool b);
|
||||||
|
|
||||||
|
bool useActiveRunway() const
|
||||||
|
{
|
||||||
|
return m_useActiveRunway;
|
||||||
|
}
|
||||||
|
|
||||||
|
Q_INVOKABLE void addToRecent(QmlPositioned* pos);
|
||||||
|
|
||||||
|
QObjectList airportRunways() const;
|
||||||
|
QObjectList airportParkings() const;
|
||||||
|
|
||||||
|
Q_INVOKABLE void showHistoryInSearchModel();
|
||||||
|
|
||||||
|
Q_INVOKABLE QmlGeod parseStringAsGeod(QString string) const;
|
||||||
|
|
||||||
|
bool tuneNAV1() const
|
||||||
|
{
|
||||||
|
return m_tuneNAV1;
|
||||||
|
}
|
||||||
|
|
||||||
|
QmlPositioned* detail() const;
|
||||||
|
|
||||||
|
bool useAvailableParking() const
|
||||||
|
{
|
||||||
|
return m_useAvailableParking;
|
||||||
|
}
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void setOffsetRadial(int offsetRadial);
|
||||||
|
|
||||||
|
void setOffsetNm(double offsetNm);
|
||||||
|
|
||||||
|
void setOffsetEnabled(bool offsetEnabled);
|
||||||
|
|
||||||
|
void setOnFinal(bool onFinal);
|
||||||
|
|
||||||
|
void setTuneNAV1(bool tuneNAV1);
|
||||||
|
|
||||||
|
void setUseAvailableParking(bool useAvailableParking);
|
||||||
|
|
||||||
|
Q_SIGNALS:
|
||||||
|
void descriptionChanged();
|
||||||
|
void offsetChanged();
|
||||||
|
void baseLocationChanged();
|
||||||
|
void configChanged();
|
||||||
|
|
||||||
|
private Q_SLOTS:
|
||||||
|
void onCollectConfig();
|
||||||
|
private:
|
||||||
|
|
||||||
|
void onSearchComplete();
|
||||||
|
|
||||||
|
void onAirportRunwayClicked(FGRunwayRef rwy);
|
||||||
|
void onAirportParkingClicked(FGParkingRef park);
|
||||||
|
|
||||||
|
|
||||||
|
void addToRecent(FGPositionedRef pos);
|
||||||
|
|
||||||
|
void setNavRadioOption();
|
||||||
|
|
||||||
|
void applyPositionOffset();
|
||||||
|
|
||||||
|
NavSearchModel* m_searchModel = nullptr;
|
||||||
|
|
||||||
|
FGPositionedRef m_location;
|
||||||
|
FGAirportRef m_airportLocation; // valid if m_location is an FGAirport
|
||||||
|
FGPositionedRef m_detailLocation; // parking stand or runway detail
|
||||||
|
bool m_locationIsLatLon = false;
|
||||||
|
SGGeod m_geodLocation;
|
||||||
|
|
||||||
|
FGPositionedList m_recentLocations;
|
||||||
|
LaunchConfig* m_config = nullptr;
|
||||||
|
QmlPositioned* m_detailQml = nullptr;
|
||||||
|
|
||||||
|
bool m_offsetEnabled = false;
|
||||||
|
int m_offsetRadial = 0;
|
||||||
|
double m_offsetNm = 0.0;
|
||||||
|
bool m_offsetBearingIsTrue = false;
|
||||||
|
int m_headingDeg = 0;
|
||||||
|
int m_altitudeFt= -9999;
|
||||||
|
int m_airspeedKnots = 120;
|
||||||
|
bool m_onFinal = false;
|
||||||
|
bool m_useActiveRunway = true;
|
||||||
|
bool m_tuneNAV1;
|
||||||
|
bool m_useAvailableParking;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // LOCATION_CONTROLLER_HXX
|
File diff suppressed because it is too large
Load diff
|
@ -1,117 +0,0 @@
|
||||||
// LocationWidget.hxx - GUI launcher dialog using Qt5
|
|
||||||
//
|
|
||||||
// Written by James Turner, started October 2015.
|
|
||||||
//
|
|
||||||
// Copyright (C) 2015 James Turner <zakalawe@mac.com>
|
|
||||||
//
|
|
||||||
// This program is free software; you can redistribute it and/or
|
|
||||||
// modify it under the terms of the GNU General Public License as
|
|
||||||
// published by the Free Software Foundation; either version 2 of the
|
|
||||||
// License, or (at your option) any later version.
|
|
||||||
//
|
|
||||||
// This program is distributed in the hope that it will be useful, but
|
|
||||||
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
||||||
// General Public License for more details.
|
|
||||||
//
|
|
||||||
// You should have received a copy of the GNU General Public License
|
|
||||||
// along with this program; if not, write to the Free Software
|
|
||||||
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|
||||||
|
|
||||||
#ifndef LOCATIONWIDGET_H
|
|
||||||
#define LOCATIONWIDGET_H
|
|
||||||
|
|
||||||
#include <QWidget>
|
|
||||||
|
|
||||||
#include <QToolButton>
|
|
||||||
|
|
||||||
#include <Navaids/positioned.hxx>
|
|
||||||
#include <Airports/airports_fwd.hxx>
|
|
||||||
|
|
||||||
#include "LaunchConfig.hxx"
|
|
||||||
#include "QtLauncher_fwd.hxx"
|
|
||||||
|
|
||||||
namespace Ui {
|
|
||||||
class LocationWidget;
|
|
||||||
}
|
|
||||||
|
|
||||||
class NavSearchModel;
|
|
||||||
|
|
||||||
class LocationWidget : public QWidget
|
|
||||||
{
|
|
||||||
Q_OBJECT
|
|
||||||
|
|
||||||
public:
|
|
||||||
explicit LocationWidget(QWidget *parent = 0);
|
|
||||||
~LocationWidget();
|
|
||||||
|
|
||||||
void setLaunchConfig(LaunchConfig* config);
|
|
||||||
|
|
||||||
QString locationDescription() const;
|
|
||||||
|
|
||||||
void setBaseLocation(FGPositionedRef ref);
|
|
||||||
|
|
||||||
void setAircraftType(LauncherAircraftType ty);
|
|
||||||
|
|
||||||
bool shouldStartPaused() const;
|
|
||||||
|
|
||||||
void setLocationProperties();
|
|
||||||
|
|
||||||
void restoreLocation(QVariantMap l);
|
|
||||||
QVariantMap saveLocation() const;
|
|
||||||
|
|
||||||
void restoreSettings();
|
|
||||||
|
|
||||||
/// used to automatically select aircraft state
|
|
||||||
bool isParkedLocation() const;
|
|
||||||
|
|
||||||
/// used to automatically select aircraft state
|
|
||||||
bool isAirborneLocation() const;
|
|
||||||
Q_SIGNALS:
|
|
||||||
void descriptionChanged(QString t);
|
|
||||||
|
|
||||||
private Q_SLOTS:
|
|
||||||
void updateDescription();
|
|
||||||
void onLocationChanged();
|
|
||||||
void onOffsetDataChanged();
|
|
||||||
void onHeadingChanged();
|
|
||||||
|
|
||||||
void onCollectConfig();
|
|
||||||
private:
|
|
||||||
|
|
||||||
void onSearch();
|
|
||||||
void onSearchResultSelected(const QModelIndex& index);
|
|
||||||
void onSearchComplete();
|
|
||||||
|
|
||||||
void onAirportRunwayClicked(FGRunwayRef rwy);
|
|
||||||
void onAirportParkingClicked(FGParkingRef park);
|
|
||||||
void onAirportHelipadClicked(FGHelipadRef pad);
|
|
||||||
|
|
||||||
void onOffsetBearingTrueChanged(bool on);
|
|
||||||
|
|
||||||
void addToRecent(FGPositionedRef pos);
|
|
||||||
|
|
||||||
void onOffsetEnabledToggled(bool on);
|
|
||||||
void onBackToSearch();
|
|
||||||
void setNavRadioOption();
|
|
||||||
void onShowHistory();
|
|
||||||
|
|
||||||
void applyPositionOffset();
|
|
||||||
|
|
||||||
Ui::LocationWidget *m_ui;
|
|
||||||
|
|
||||||
NavSearchModel* m_searchModel;
|
|
||||||
|
|
||||||
FGPositionedRef m_location;
|
|
||||||
bool m_locationIsLatLon;
|
|
||||||
SGGeod m_geodLocation;
|
|
||||||
|
|
||||||
QToolButton* m_backButton;
|
|
||||||
|
|
||||||
FGPositionedList m_recentLocations;
|
|
||||||
LauncherAircraftType m_aircraftType;
|
|
||||||
|
|
||||||
LaunchConfig* m_config = nullptr;
|
|
||||||
};
|
|
||||||
|
|
||||||
#endif // LOCATIONWIDGET_H
|
|
|
@ -1,442 +0,0 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<ui version="4.0">
|
|
||||||
<class>LocationWidget</class>
|
|
||||||
<widget class="QWidget" name="LocationWidget">
|
|
||||||
<property name="geometry">
|
|
||||||
<rect>
|
|
||||||
<x>0</x>
|
|
||||||
<y>0</y>
|
|
||||||
<width>864</width>
|
|
||||||
<height>683</height>
|
|
||||||
</rect>
|
|
||||||
</property>
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QStackedWidget" name="stack">
|
|
||||||
<property name="currentIndex">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<widget class="QWidget" name="airportPage">
|
|
||||||
<layout class="QGridLayout" name="gridLayout" columnstretch="1,0,0,0">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item row="5" column="2">
|
|
||||||
<widget class="QSpinBox" name="approachDistanceSpin">
|
|
||||||
<property name="suffix">
|
|
||||||
<string>nm</string>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<number>10</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="6" column="0">
|
|
||||||
<widget class="QRadioButton" name="parkingRadio">
|
|
||||||
<property name="text">
|
|
||||||
<string>Parking:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="0">
|
|
||||||
<widget class="QRadioButton" name="runwayRadio">
|
|
||||||
<property name="text">
|
|
||||||
<string>Runway:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="6" column="1" colspan="3">
|
|
||||||
<widget class="QComboBox" name="parkingCombo"/>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="3">
|
|
||||||
<spacer name="horizontalSpacer">
|
|
||||||
<property name="orientation">
|
|
||||||
<enum>Qt::Horizontal</enum>
|
|
||||||
</property>
|
|
||||||
<property name="sizeHint" stdset="0">
|
|
||||||
<size>
|
|
||||||
<width>40</width>
|
|
||||||
<height>20</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</spacer>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="1" colspan="3">
|
|
||||||
<widget class="QComboBox" name="runwayCombo"/>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="1">
|
|
||||||
<widget class="QCheckBox" name="onFinalCheckbox">
|
|
||||||
<property name="text">
|
|
||||||
<string>On final approach at distance:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="2" column="0" colspan="4">
|
|
||||||
<widget class="QLabel" name="titleLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string>TextLabel</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="3" column="0" colspan="4">
|
|
||||||
<widget class="AirportDiagram" name="airportDiagram" native="true">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="MinimumExpanding" vsizetype="MinimumExpanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<widget class="QWidget" name="navaidPage">
|
|
||||||
<layout class="QGridLayout" name="gridLayout_3" rowstretch="0,1,0,0,0,0" columnstretch="1,0,0,1,0,1,0,0,0,0">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item row="4" column="6" colspan="2">
|
|
||||||
<widget class="QSpinBox" name="altitudeSpinbox">
|
|
||||||
<property name="suffix">
|
|
||||||
<string>ft</string>
|
|
||||||
</property>
|
|
||||||
<property name="minimum">
|
|
||||||
<number>-1000</number>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>120000</number>
|
|
||||||
</property>
|
|
||||||
<property name="singleStep">
|
|
||||||
<number>50</number>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<number>5000</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="8" colspan="2">
|
|
||||||
<widget class="QComboBox" name="altitudeModeCombo">
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Barometric altitude (ASL)</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Above ground (AGL)</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<property name="text">
|
|
||||||
<string>Flight Level (FL)</string>
|
|
||||||
</property>
|
|
||||||
</item>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="5">
|
|
||||||
<widget class="QLabel" name="altitudeLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string>Altitude:</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="5" column="0" colspan="10">
|
|
||||||
<widget class="QGroupBox" name="offsetGroup">
|
|
||||||
<property name="title">
|
|
||||||
<string>Offset</string>
|
|
||||||
</property>
|
|
||||||
<property name="checkable">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="checked">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_2" stretch="1,0,0,1,0">
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>4</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>4</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>4</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>4</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="offsetBearingLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string>Bearing:</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QSpinBox" name="offsetBearingSpinbox">
|
|
||||||
<property name="wrapping">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>359</number>
|
|
||||||
</property>
|
|
||||||
<property name="singleStep">
|
|
||||||
<number>5</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QCheckBox" name="trueBearing">
|
|
||||||
<property name="text">
|
|
||||||
<string>True</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="offsetDistanceLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string>Distance:</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QDoubleSpinBox" name="offsetNmSpinbox">
|
|
||||||
<property name="suffix">
|
|
||||||
<string>nm</string>
|
|
||||||
</property>
|
|
||||||
<property name="decimals">
|
|
||||||
<number>1</number>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<double>10000.000000000000000</double>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<double>10.000000000000000</double>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="0">
|
|
||||||
<widget class="QLabel" name="aispeedLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string>Airspeed:</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="3">
|
|
||||||
<widget class="QLabel" name="label">
|
|
||||||
<property name="text">
|
|
||||||
<string>Heading:</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignRight|Qt::AlignTrailing|Qt::AlignVCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="4">
|
|
||||||
<widget class="QSpinBox" name="headingSpinbox">
|
|
||||||
<property name="wrapping">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>359</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="4" column="1" colspan="2">
|
|
||||||
<widget class="QSpinBox" name="airspeedSpinbox">
|
|
||||||
<property name="suffix">
|
|
||||||
<string>kts</string>
|
|
||||||
</property>
|
|
||||||
<property name="maximum">
|
|
||||||
<number>9999</number>
|
|
||||||
</property>
|
|
||||||
<property name="value">
|
|
||||||
<number>120</number>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="0" column="0" colspan="10">
|
|
||||||
<widget class="QLabel" name="navTitleLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string>TextLabel</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item row="1" column="0" colspan="10">
|
|
||||||
<widget class="NavaidDiagram" name="navaidDiagram" native="true">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Expanding" vsizetype="Expanding">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>200</width>
|
|
||||||
<height>200</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<widget class="QWidget" name="searchPage">
|
|
||||||
<layout class="QVBoxLayout" name="verticalLayout_2">
|
|
||||||
<property name="spacing">
|
|
||||||
<number>2</number>
|
|
||||||
</property>
|
|
||||||
<property name="leftMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="topMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="rightMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<property name="bottomMargin">
|
|
||||||
<number>0</number>
|
|
||||||
</property>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout_6">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="searchLabel">
|
|
||||||
<property name="text">
|
|
||||||
<string>Search:</string>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLineEdit" name="locationSearchEdit">
|
|
||||||
<property name="placeholderText">
|
|
||||||
<string>Enter an ICAO code, navaid or name, then press Enter</string>
|
|
||||||
</property>
|
|
||||||
<property name="clearButtonEnabled">
|
|
||||||
<bool>true</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QPushButton" name="searchHistory">
|
|
||||||
<property name="sizePolicy">
|
|
||||||
<sizepolicy hsizetype="Fixed" vsizetype="Fixed">
|
|
||||||
<horstretch>0</horstretch>
|
|
||||||
<verstretch>0</verstretch>
|
|
||||||
</sizepolicy>
|
|
||||||
</property>
|
|
||||||
<property name="autoDefault">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
<property name="flat">
|
|
||||||
<bool>false</bool>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<layout class="QHBoxLayout" name="horizontalLayout" stretch="1,0">
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="searchStatusText">
|
|
||||||
<property name="text">
|
|
||||||
<string/>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignHCenter|Qt::AlignTop</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QLabel" name="searchIcon">
|
|
||||||
<property name="minimumSize">
|
|
||||||
<size>
|
|
||||||
<width>16</width>
|
|
||||||
<height>16</height>
|
|
||||||
</size>
|
|
||||||
</property>
|
|
||||||
<property name="text">
|
|
||||||
<string>TextLabel</string>
|
|
||||||
</property>
|
|
||||||
<property name="alignment">
|
|
||||||
<set>Qt::AlignBottom|Qt::AlignHCenter</set>
|
|
||||||
</property>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</item>
|
|
||||||
<item>
|
|
||||||
<widget class="QListView" name="searchResultsList"/>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
</widget>
|
|
||||||
</item>
|
|
||||||
</layout>
|
|
||||||
</widget>
|
|
||||||
<customwidgets>
|
|
||||||
<customwidget>
|
|
||||||
<class>AirportDiagram</class>
|
|
||||||
<extends>QWidget</extends>
|
|
||||||
<header location="global">GUI/AirportDiagram.hxx</header>
|
|
||||||
<container>1</container>
|
|
||||||
</customwidget>
|
|
||||||
<customwidget>
|
|
||||||
<class>NavaidDiagram</class>
|
|
||||||
<extends>QWidget</extends>
|
|
||||||
<header location="global">GUI/NavaidDiagram.hxx</header>
|
|
||||||
<container>1</container>
|
|
||||||
</customwidget>
|
|
||||||
</customwidgets>
|
|
||||||
<resources/>
|
|
||||||
<connections/>
|
|
||||||
</ui>
|
|
|
@ -27,7 +27,9 @@
|
||||||
#include <QVector2D>
|
#include <QVector2D>
|
||||||
#include <QMouseEvent>
|
#include <QMouseEvent>
|
||||||
|
|
||||||
NavaidDiagram::NavaidDiagram(QWidget* pr) :
|
#include <Navaids/NavDataCache.hxx>
|
||||||
|
|
||||||
|
NavaidDiagram::NavaidDiagram(QQuickItem* pr) :
|
||||||
BaseDiagram(pr),
|
BaseDiagram(pr),
|
||||||
m_offsetEnabled(false),
|
m_offsetEnabled(false),
|
||||||
m_offsetDistanceNm(5.0),
|
m_offsetDistanceNm(5.0),
|
||||||
|
@ -37,12 +39,28 @@ NavaidDiagram::NavaidDiagram(QWidget* pr) :
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavaidDiagram::setNavaid(FGPositionedRef nav)
|
void NavaidDiagram::setNavaid(qlonglong nav)
|
||||||
{
|
{
|
||||||
m_navaid = nav;
|
m_navaid = fgpositioned_cast<FGNavRecord>(flightgear::NavDataCache::instance()->loadById(nav));
|
||||||
m_projectionCenter = nav ? nav->geod() : SGGeod();
|
m_projectionCenter = m_navaid ? m_navaid->geod() : SGGeod();
|
||||||
m_geod = nav->geod();
|
m_geod = m_projectionCenter;
|
||||||
recomputeBounds(true);
|
recomputeBounds(true);
|
||||||
|
emit locationChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
qlonglong NavaidDiagram::navaid() const
|
||||||
|
{
|
||||||
|
return m_navaid->guid();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NavaidDiagram::setGeod(QmlGeod geod)
|
||||||
|
{
|
||||||
|
setGeod(geod.geod());
|
||||||
|
}
|
||||||
|
|
||||||
|
QmlGeod NavaidDiagram::geod() const
|
||||||
|
{
|
||||||
|
return QmlGeod(m_geod);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavaidDiagram::setGeod(const SGGeod &geod)
|
void NavaidDiagram::setGeod(const SGGeod &geod)
|
||||||
|
@ -51,6 +69,7 @@ void NavaidDiagram::setGeod(const SGGeod &geod)
|
||||||
m_geod = geod;
|
m_geod = geod;
|
||||||
m_projectionCenter = m_geod;
|
m_projectionCenter = m_geod;
|
||||||
recomputeBounds(true);
|
recomputeBounds(true);
|
||||||
|
emit locationChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavaidDiagram::setOffsetEnabled(bool offset)
|
void NavaidDiagram::setOffsetEnabled(bool offset)
|
||||||
|
@ -59,24 +78,28 @@ void NavaidDiagram::setOffsetEnabled(bool offset)
|
||||||
return;
|
return;
|
||||||
m_offsetEnabled = offset;
|
m_offsetEnabled = offset;
|
||||||
recomputeBounds(true);
|
recomputeBounds(true);
|
||||||
|
emit offsetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavaidDiagram::setOffsetDistanceNm(double distanceNm)
|
void NavaidDiagram::setOffsetDistanceNm(double distanceNm)
|
||||||
{
|
{
|
||||||
m_offsetDistanceNm = distanceNm;
|
m_offsetDistanceNm = distanceNm;
|
||||||
update();
|
update();
|
||||||
|
emit offsetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavaidDiagram::setOffsetBearingDeg(int bearingDeg)
|
void NavaidDiagram::setOffsetBearingDeg(int bearingDeg)
|
||||||
{
|
{
|
||||||
m_offsetBearingDeg = bearingDeg;
|
m_offsetBearingDeg = bearingDeg;
|
||||||
update();
|
update();
|
||||||
|
emit offsetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavaidDiagram::setHeadingDeg(int headingDeg)
|
void NavaidDiagram::setHeadingDeg(int headingDeg)
|
||||||
{
|
{
|
||||||
m_headingDeg = headingDeg;
|
m_headingDeg = headingDeg;
|
||||||
update();
|
update();
|
||||||
|
emit offsetChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NavaidDiagram::paintContents(QPainter *painter)
|
void NavaidDiagram::paintContents(QPainter *painter)
|
||||||
|
|
|
@ -22,7 +22,7 @@
|
||||||
#define GUI_NAVAID_DIAGRAM_HXX
|
#define GUI_NAVAID_DIAGRAM_HXX
|
||||||
|
|
||||||
#include "BaseDiagram.hxx"
|
#include "BaseDiagram.hxx"
|
||||||
#include <QPainterPath>
|
#include "QmlPositioned.hxx"
|
||||||
|
|
||||||
#include <Navaids/navrecord.hxx>
|
#include <Navaids/navrecord.hxx>
|
||||||
#include <simgear/math/sg_geodesy.hxx>
|
#include <simgear/math/sg_geodesy.hxx>
|
||||||
|
@ -30,28 +30,50 @@
|
||||||
class NavaidDiagram : public BaseDiagram
|
class NavaidDiagram : public BaseDiagram
|
||||||
{
|
{
|
||||||
Q_OBJECT
|
Q_OBJECT
|
||||||
public:
|
|
||||||
NavaidDiagram(QWidget* pr);
|
|
||||||
|
|
||||||
void setNavaid(FGPositionedRef nav);
|
Q_PROPERTY(qlonglong navaid READ navaid WRITE setNavaid NOTIFY locationChanged)
|
||||||
|
Q_PROPERTY(QmlGeod geod READ geod WRITE setGeod NOTIFY locationChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(int headingDeg READ headingDeg WRITE setHeadingDeg NOTIFY offsetChanged)
|
||||||
|
Q_PROPERTY(int offsetBearingDeg READ offsetBearingDeg WRITE setOffsetBearingDeg NOTIFY offsetChanged)
|
||||||
|
Q_PROPERTY(bool offsetEnabled READ isOffsetEnabled WRITE setOffsetEnabled NOTIFY offsetChanged)
|
||||||
|
Q_PROPERTY(double offsetDistanceNm READ offsetDistanceNm WRITE setOffsetDistanceNm NOTIFY offsetChanged)
|
||||||
|
public:
|
||||||
|
NavaidDiagram(QQuickItem* pr = nullptr);
|
||||||
|
|
||||||
|
void setNavaid(qlonglong nav);
|
||||||
|
qlonglong navaid() const;
|
||||||
|
|
||||||
|
void setGeod(QmlGeod geod);
|
||||||
|
QmlGeod geod() const;
|
||||||
|
|
||||||
void setGeod(const SGGeod& geod);
|
void setGeod(const SGGeod& geod);
|
||||||
|
|
||||||
bool isOffsetEnabled() const;
|
bool isOffsetEnabled() const
|
||||||
|
{ return m_offsetEnabled; }
|
||||||
|
|
||||||
void setOffsetEnabled(bool offset);
|
void setOffsetEnabled(bool offset);
|
||||||
|
|
||||||
void setOffsetDistanceNm(double distanceNm);
|
void setOffsetDistanceNm(double distanceNm);
|
||||||
double offsetDistanceNm() const;
|
double offsetDistanceNm() const
|
||||||
|
{ return m_offsetDistanceNm; }
|
||||||
|
|
||||||
void setOffsetBearingDeg(int bearingDeg);
|
void setOffsetBearingDeg(int bearingDeg);
|
||||||
int offsetBearingDeg() const;
|
int offsetBearingDeg() const
|
||||||
|
{ return m_offsetBearingDeg; }
|
||||||
|
|
||||||
void setHeadingDeg(int headingDeg);
|
void setHeadingDeg(int headingDeg);
|
||||||
void headingDeg() const;
|
int headingDeg() const
|
||||||
protected:
|
{ return m_headingDeg; }
|
||||||
void paintContents(QPainter *) Q_DECL_OVERRIDE;
|
|
||||||
|
|
||||||
void doComputeBounds() Q_DECL_OVERRIDE;
|
signals:
|
||||||
|
void locationChanged();
|
||||||
|
void offsetChanged();
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void paintContents(QPainter *) override;
|
||||||
|
|
||||||
|
void doComputeBounds() override;
|
||||||
private:
|
private:
|
||||||
FGPositionedRef m_navaid;
|
FGPositionedRef m_navaid;
|
||||||
SGGeod m_geod;
|
SGGeod m_geod;
|
||||||
|
|
50
src/GUI/PixmapImageItem.cxx
Normal file
50
src/GUI/PixmapImageItem.cxx
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
// PixmapImageItem.cxx - display a QPixmap/QImage directly
|
||||||
|
//
|
||||||
|
// Written by James Turner, started April 2018.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2018 James Turner <james@flightgear.org>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#include "PixmapImageItem.hxx"
|
||||||
|
|
||||||
|
#include <QPainter>
|
||||||
|
|
||||||
|
PixmapImageItem::PixmapImageItem(QQuickItem* parent) :
|
||||||
|
QQuickPaintedItem(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
void PixmapImageItem::paint(QPainter *painter)
|
||||||
|
{
|
||||||
|
if (_image.isNull())
|
||||||
|
return;
|
||||||
|
|
||||||
|
QRect rect(0, 0, width(), height());
|
||||||
|
painter->drawImage(rect, _image);
|
||||||
|
}
|
||||||
|
|
||||||
|
void PixmapImageItem::setImage(QImage img)
|
||||||
|
{
|
||||||
|
if (img == _image)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_image = img;
|
||||||
|
update();
|
||||||
|
const auto sz = img.size();
|
||||||
|
setImplicitSize(sz.width(), sz.height());
|
||||||
|
emit imageChanged();
|
||||||
|
}
|
50
src/GUI/PixmapImageItem.hxx
Normal file
50
src/GUI/PixmapImageItem.hxx
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
// PixmapImageItem.hxx - display a QPixmap/QImage directly
|
||||||
|
//
|
||||||
|
// Written by James Turner, started April 2018.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2018 James Turner <james@flightgear.org>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
|
||||||
|
#ifndef PIXMAPIMAGEITEM_HXX
|
||||||
|
#define PIXMAPIMAGEITEM_HXX
|
||||||
|
|
||||||
|
#include <QQuickPaintedItem>
|
||||||
|
#include <QImage>
|
||||||
|
|
||||||
|
class PixmapImageItem : public QQuickPaintedItem
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
|
||||||
|
Q_PROPERTY(QImage image READ image WRITE setImage NOTIFY imageChanged)
|
||||||
|
public:
|
||||||
|
PixmapImageItem(QQuickItem* parent = nullptr);
|
||||||
|
|
||||||
|
void paint(QPainter* painter) override;
|
||||||
|
|
||||||
|
QImage image() const
|
||||||
|
{ return _image; }
|
||||||
|
|
||||||
|
void setImage(QImage img);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void imageChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
QImage _image;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // PIXMAPIMAGEITEM_HXX
|
26
src/GUI/QmlNavCacheWrapper.cxx
Normal file
26
src/GUI/QmlNavCacheWrapper.cxx
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
// QmlNavCacheWrapper.cxx - Expose NavData to Qml
|
||||||
|
//
|
||||||
|
// Written by James Turner, started April 2018.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2018 James Turner <james@flightgear.org>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#include "QmlNavCacheWrapper.hxx"
|
||||||
|
|
||||||
|
QmlNavCacheWrapper::QmlNavCacheWrapper()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
38
src/GUI/QmlNavCacheWrapper.hxx
Normal file
38
src/GUI/QmlNavCacheWrapper.hxx
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
// QmlNavCacheWrapper.hxx - Expose NavData to Qml
|
||||||
|
//
|
||||||
|
// Written by James Turner, started April 2018.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2018 James Turner <james@flightgear.org>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#ifndef QMLNAVCACHEWRAPPER_HXX
|
||||||
|
#define QMLNAVCACHEWRAPPER_HXX
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief QmlNavCacheWrapper wraps and exposes NavData to Qml as singleton
|
||||||
|
* service
|
||||||
|
*/
|
||||||
|
class QmlNavCacheWrapper : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
|
||||||
|
QmlNavCacheWrapper();
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // QMLNAVCACHEWRAPPER_HXX
|
317
src/GUI/QmlPositioned.cxx
Normal file
317
src/GUI/QmlPositioned.cxx
Normal file
|
@ -0,0 +1,317 @@
|
||||||
|
// QmlPositioned.cxx - Expose NavData to Qml
|
||||||
|
//
|
||||||
|
// Written by James Turner, started April 2018.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2018 James Turner <james@flightgear.org>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#include "QmlPositioned.hxx"
|
||||||
|
|
||||||
|
#include <QDebug>
|
||||||
|
|
||||||
|
#include <Navaids/NavDataCache.hxx>
|
||||||
|
#include <Navaids/navrecord.hxx>
|
||||||
|
#include <Airports/airport.hxx>
|
||||||
|
#include <Airports/groundnetwork.hxx>
|
||||||
|
#include <Airports/runways.hxx>
|
||||||
|
|
||||||
|
using namespace flightgear;
|
||||||
|
|
||||||
|
QmlGeod::QmlGeod() :
|
||||||
|
m_data(SGGeod::fromDeg(-9999.0, -9999.0))
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
QmlGeod::QmlGeod(const SGGeod &geod) :
|
||||||
|
m_data(geod)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
double QmlGeod::latitudeDeg() const
|
||||||
|
{
|
||||||
|
return m_data.getLatitudeDeg();
|
||||||
|
}
|
||||||
|
|
||||||
|
double QmlGeod::longitudeDeg() const
|
||||||
|
{
|
||||||
|
return m_data.getLongitudeDeg();
|
||||||
|
}
|
||||||
|
|
||||||
|
double QmlGeod::latitudeRad() const
|
||||||
|
{
|
||||||
|
return m_data.getLatitudeRad();
|
||||||
|
}
|
||||||
|
|
||||||
|
double QmlGeod::longitudeRad() const
|
||||||
|
{
|
||||||
|
return m_data.getLongitudeRad();
|
||||||
|
}
|
||||||
|
|
||||||
|
double QmlGeod::elevationFt() const
|
||||||
|
{
|
||||||
|
return m_data.getElevationFt();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QmlGeod::valid() const
|
||||||
|
{
|
||||||
|
return m_data.isValid();
|
||||||
|
}
|
||||||
|
|
||||||
|
double QmlGeod::elevationM() const
|
||||||
|
{
|
||||||
|
return m_data.getElevationM();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlGeod::setLatitudeDeg(double latitudeDeg)
|
||||||
|
{
|
||||||
|
if (qFuzzyCompare(m_data.getLatitudeDeg(), latitudeDeg))
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_data.setLatitudeDeg(latitudeDeg);
|
||||||
|
// emit latitudeChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlGeod::setLongitudeDeg(double longitudeDeg)
|
||||||
|
{
|
||||||
|
if (qFuzzyCompare(m_data.getLongitudeDeg(), longitudeDeg))
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_data.setLongitudeDeg(longitudeDeg);
|
||||||
|
// emit longitudeChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlGeod::setLatitudeRad(double latitudeRad)
|
||||||
|
{
|
||||||
|
if (qFuzzyCompare(m_data.getLatitudeRad(), latitudeRad))
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_data.setLatitudeRad(latitudeRad);
|
||||||
|
// emit latitudeChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlGeod::setLongitudeRad(double longitudeRad)
|
||||||
|
{
|
||||||
|
if (qFuzzyCompare(m_data.getLongitudeRad(), longitudeRad))
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_data.setLongitudeRad(longitudeRad);
|
||||||
|
// emit longitudeChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlGeod::setElevationM(double elevationM)
|
||||||
|
{
|
||||||
|
if (qFuzzyCompare(m_data.getElevationM(), elevationM))
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_data.setElevationM(elevationM);
|
||||||
|
// emit elevationChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlGeod::setElevationFt(double elevationFt)
|
||||||
|
{
|
||||||
|
if (qFuzzyCompare(m_data.getElevationFt(), elevationFt))
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_data.setElevationFt(elevationFt);
|
||||||
|
// emit elevationChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
/////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
QmlPositioned::QmlPositioned(QObject *parent) : QObject(parent)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
QmlPositioned::QmlPositioned(FGPositionedRef p) :
|
||||||
|
m_pos(p)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlPositioned::setInner(FGPositionedRef p)
|
||||||
|
{
|
||||||
|
if (!p) {
|
||||||
|
m_pos.clear();
|
||||||
|
} else {
|
||||||
|
m_pos = p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FGPositionedRef QmlPositioned::inner() const
|
||||||
|
{
|
||||||
|
return m_pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QmlPositioned::valid() const
|
||||||
|
{
|
||||||
|
return m_pos.valid();
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QmlPositioned::ident() const
|
||||||
|
{
|
||||||
|
if (!m_pos)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
return QString::fromStdString(m_pos->ident());
|
||||||
|
}
|
||||||
|
|
||||||
|
QString QmlPositioned::name() const
|
||||||
|
{
|
||||||
|
if (!m_pos)
|
||||||
|
return {};
|
||||||
|
|
||||||
|
return QString::fromStdString(m_pos->name());
|
||||||
|
}
|
||||||
|
|
||||||
|
qlonglong QmlPositioned::guid() const
|
||||||
|
{
|
||||||
|
if (!m_pos)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
return m_pos->guid();
|
||||||
|
}
|
||||||
|
|
||||||
|
QmlPositioned::Type QmlPositioned::type() const
|
||||||
|
{
|
||||||
|
if (!m_pos)
|
||||||
|
return Invalid;
|
||||||
|
|
||||||
|
return static_cast<Type>(m_pos->type());
|
||||||
|
}
|
||||||
|
|
||||||
|
void QmlPositioned::setGuid(qlonglong guid)
|
||||||
|
{
|
||||||
|
if (m_pos && (m_pos->guid()) == guid)
|
||||||
|
return;
|
||||||
|
|
||||||
|
m_pos = NavDataCache::instance()->loadById(guid);
|
||||||
|
|
||||||
|
emit guidChanged();
|
||||||
|
emit infoChanged();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QmlPositioned::isAirportType() const
|
||||||
|
{
|
||||||
|
return FGPositioned::isAirportType(m_pos.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QmlPositioned::isRunwayType() const
|
||||||
|
{
|
||||||
|
return FGPositioned::isRunwayType(m_pos.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QmlPositioned::isNavaidType() const
|
||||||
|
{
|
||||||
|
return FGPositioned::isNavaidType(m_pos.get());
|
||||||
|
}
|
||||||
|
|
||||||
|
QmlGeod* QmlPositioned::geod() const
|
||||||
|
{
|
||||||
|
if (!m_pos)
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return new QmlGeod(m_pos->geod());
|
||||||
|
}
|
||||||
|
|
||||||
|
double QmlPositioned::navaidFrequencyMHz() const
|
||||||
|
{
|
||||||
|
FGNavRecord* nav = fgpositioned_cast<FGNavRecord>(m_pos);
|
||||||
|
if (!nav)
|
||||||
|
return 0.0;
|
||||||
|
|
||||||
|
qWarning() << Q_FUNC_INFO << "check me!";
|
||||||
|
return nav->get_freq() / 1000.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
double QmlPositioned::navaidRangeNm() const
|
||||||
|
{
|
||||||
|
FGNavRecord* nav = fgpositioned_cast<FGNavRecord>(m_pos);
|
||||||
|
if (!nav)
|
||||||
|
return 0.0;
|
||||||
|
|
||||||
|
return nav->get_range();
|
||||||
|
}
|
||||||
|
|
||||||
|
QmlPositioned *QmlPositioned::navaidRunway() const
|
||||||
|
{
|
||||||
|
FGNavRecord* nav = fgpositioned_cast<FGNavRecord>(m_pos);
|
||||||
|
if (!nav || !nav->runway())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return new QmlPositioned(nav->runway());
|
||||||
|
}
|
||||||
|
|
||||||
|
QmlPositioned *QmlPositioned::colocatedDME() const
|
||||||
|
{
|
||||||
|
FGNavRecord* nav = fgpositioned_cast<FGNavRecord>(m_pos);
|
||||||
|
if (!nav || !nav->hasDME())
|
||||||
|
return nullptr;
|
||||||
|
|
||||||
|
return new QmlPositioned(flightgear::NavDataCache::instance()->loadById(nav->colocatedDME()));
|
||||||
|
}
|
||||||
|
|
||||||
|
QmlPositioned *QmlPositioned::owningAirport() const
|
||||||
|
{
|
||||||
|
FGRunway* runway = fgpositioned_cast<FGRunway>(m_pos);
|
||||||
|
if (runway) {
|
||||||
|
return new QmlPositioned(runway->airport());
|
||||||
|
}
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
double QmlPositioned::runwayHeadingDeg() const
|
||||||
|
{
|
||||||
|
FGRunway* runway = fgpositioned_cast<FGRunway>(m_pos);
|
||||||
|
if (runway) {
|
||||||
|
return runway->headingDeg();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
double QmlPositioned::runwayLengthFt() const
|
||||||
|
{
|
||||||
|
FGRunway* runway = fgpositioned_cast<FGRunway>(m_pos);
|
||||||
|
if (runway) {
|
||||||
|
return runway->lengthFt();
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QmlPositioned::equals(QmlPositioned *other) const
|
||||||
|
{
|
||||||
|
return (other && (other->inner() == inner()));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool QmlPositioned::airportHasParkings() const
|
||||||
|
{
|
||||||
|
if (!isAirportType())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
FGAirport* apt = fgpositioned_cast<FGAirport>(m_pos);
|
||||||
|
if (!apt)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return !apt->groundNetwork()->allParkings().empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool operator==(const QmlPositioned& p1, const QmlPositioned& p2)
|
||||||
|
{
|
||||||
|
return p1.inner() == p2.inner();
|
||||||
|
}
|
||||||
|
|
186
src/GUI/QmlPositioned.hxx
Normal file
186
src/GUI/QmlPositioned.hxx
Normal file
|
@ -0,0 +1,186 @@
|
||||||
|
// QmlPositioned.hxx - Expose NavData to Qml
|
||||||
|
//
|
||||||
|
// Written by James Turner, started April 2018.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2018 James Turner <james@flightgear.org>
|
||||||
|
//
|
||||||
|
// This program is free software; you can redistribute it and/or
|
||||||
|
// modify it under the terms of the GNU General Public License as
|
||||||
|
// published by the Free Software Foundation; either version 2 of the
|
||||||
|
// License, or (at your option) any later version.
|
||||||
|
//
|
||||||
|
// This program is distributed in the hope that it will be useful, but
|
||||||
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
// General Public License for more details.
|
||||||
|
//
|
||||||
|
// You should have received a copy of the GNU General Public License
|
||||||
|
// along with this program; if not, write to the Free Software
|
||||||
|
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||||
|
|
||||||
|
#ifndef QMLPOSITIONED_HXX
|
||||||
|
#define QMLPOSITIONED_HXX
|
||||||
|
|
||||||
|
#include <QObject>
|
||||||
|
|
||||||
|
#include <Navaids/positioned.hxx>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Expose an SGGeod as Qml-friendly class
|
||||||
|
*/
|
||||||
|
class QmlGeod
|
||||||
|
{
|
||||||
|
Q_GADGET
|
||||||
|
|
||||||
|
|
||||||
|
Q_PROPERTY(double latitudeDeg READ latitudeDeg WRITE setLatitudeDeg)
|
||||||
|
Q_PROPERTY(double longitudeDeg READ longitudeDeg WRITE setLongitudeDeg)
|
||||||
|
|
||||||
|
Q_PROPERTY(double latitudeRad READ latitudeRad WRITE setLatitudeRad)
|
||||||
|
Q_PROPERTY(double longitudeRad READ longitudeRad WRITE setLongitudeRad)
|
||||||
|
|
||||||
|
Q_PROPERTY(double elevationM READ elevationM WRITE setElevationM)
|
||||||
|
Q_PROPERTY(double elevationFt READ elevationFt WRITE setElevationFt)
|
||||||
|
|
||||||
|
Q_PROPERTY(bool valid READ valid)
|
||||||
|
public:
|
||||||
|
QmlGeod();
|
||||||
|
QmlGeod(const SGGeod& geod);
|
||||||
|
|
||||||
|
SGGeod geod() const
|
||||||
|
{ return m_data; }
|
||||||
|
|
||||||
|
|
||||||
|
double latitudeDeg() const;
|
||||||
|
double longitudeDeg() const;
|
||||||
|
double latitudeRad() const;
|
||||||
|
double longitudeRad() const;
|
||||||
|
double elevationM() const;
|
||||||
|
double elevationFt() const;
|
||||||
|
|
||||||
|
bool valid() const;
|
||||||
|
public slots:
|
||||||
|
void setLatitudeDeg(double latitudeDeg);
|
||||||
|
void setLongitudeDeg(double longitudeDeg);
|
||||||
|
void setLatitudeRad(double latitudeRad);
|
||||||
|
void setLongitudeRad(double longitudeRad);
|
||||||
|
void setElevationM(double elevationM);
|
||||||
|
void setElevationFt(double elevationFt);
|
||||||
|
|
||||||
|
private:
|
||||||
|
SGGeod m_data;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
Q_DECLARE_METATYPE(QmlGeod)
|
||||||
|
|
||||||
|
class QmlPositioned : public QObject
|
||||||
|
{
|
||||||
|
Q_OBJECT
|
||||||
|
public:
|
||||||
|
explicit QmlPositioned(QObject *parent = nullptr);
|
||||||
|
|
||||||
|
explicit QmlPositioned(FGPositionedRef p);
|
||||||
|
|
||||||
|
// proxy FGPositioned type values
|
||||||
|
enum Type {
|
||||||
|
Invalid = FGPositioned::INVALID,
|
||||||
|
Airport = FGPositioned::AIRPORT,
|
||||||
|
Heliport = FGPositioned::HELIPORT,
|
||||||
|
Seaport = FGPositioned::SEAPORT,
|
||||||
|
Runway = FGPositioned::RUNWAY,
|
||||||
|
Helipad = FGPositioned::HELIPAD,
|
||||||
|
Taxiway = FGPositioned::TAXIWAY,
|
||||||
|
Pavement = FGPositioned::PAVEMENT,
|
||||||
|
Waypoint = FGPositioned::WAYPOINT,
|
||||||
|
Fix = FGPositioned::FIX,
|
||||||
|
NDB = FGPositioned::NDB,
|
||||||
|
VOR = FGPositioned::VOR,
|
||||||
|
ILS = FGPositioned::ILS,
|
||||||
|
Localizer = FGPositioned::LOC,
|
||||||
|
Glideslope = FGPositioned::GS,
|
||||||
|
OuterMarker = FGPositioned::OM,
|
||||||
|
MiddleMarker = FGPositioned::MM,
|
||||||
|
InnerMarker = FGPositioned::IM,
|
||||||
|
DME = FGPositioned::DME,
|
||||||
|
TACAN = FGPositioned::TACAN,
|
||||||
|
MobileTACAN = FGPositioned::MOBILE_TACAN,
|
||||||
|
Tower = FGPositioned::TOWER,
|
||||||
|
Parking = FGPositioned::PARKING,
|
||||||
|
Country = FGPositioned::COUNTRY,
|
||||||
|
City = FGPositioned::CITY,
|
||||||
|
Town = FGPositioned::TOWN,
|
||||||
|
Village = FGPositioned::VILLAGE
|
||||||
|
};
|
||||||
|
|
||||||
|
Q_ENUM(Type)
|
||||||
|
|
||||||
|
Q_PROPERTY(QString ident READ ident NOTIFY infoChanged)
|
||||||
|
Q_PROPERTY(QString name READ name NOTIFY infoChanged)
|
||||||
|
Q_PROPERTY(Type type READ type NOTIFY infoChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(bool valid READ valid NOTIFY infoChanged)
|
||||||
|
Q_PROPERTY(QmlGeod* geod READ geod NOTIFY infoChanged)
|
||||||
|
Q_PROPERTY(qlonglong guid READ guid WRITE setGuid NOTIFY guidChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(bool isAirportType READ isAirportType NOTIFY infoChanged)
|
||||||
|
Q_PROPERTY(bool isRunwayType READ isRunwayType NOTIFY infoChanged)
|
||||||
|
Q_PROPERTY(bool isNavaidType READ isNavaidType NOTIFY infoChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(double navaidFrequencyMHz READ navaidFrequencyMHz NOTIFY infoChanged)
|
||||||
|
Q_PROPERTY(double navaidRangeNm READ navaidRangeNm NOTIFY infoChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(QmlPositioned* colocatedDME READ colocatedDME NOTIFY infoChanged)
|
||||||
|
Q_PROPERTY(QmlPositioned* navaidRunway READ navaidRunway NOTIFY infoChanged)
|
||||||
|
Q_PROPERTY(QmlPositioned* owningAirport READ owningAirport NOTIFY infoChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(double runwayHeadingDeg READ runwayHeadingDeg NOTIFY infoChanged)
|
||||||
|
Q_PROPERTY(double runwayLengthFt READ runwayLengthFt NOTIFY infoChanged)
|
||||||
|
|
||||||
|
Q_PROPERTY(bool airportHasParkings READ airportHasParkings NOTIFY infoChanged)
|
||||||
|
|
||||||
|
void setInner(FGPositionedRef p);
|
||||||
|
FGPositionedRef inner() const;
|
||||||
|
bool valid() const;
|
||||||
|
|
||||||
|
QString ident() const;
|
||||||
|
QString name() const;
|
||||||
|
qlonglong guid() const;
|
||||||
|
Type type() const;
|
||||||
|
|
||||||
|
bool isAirportType() const;
|
||||||
|
bool isRunwayType() const;
|
||||||
|
bool isNavaidType() const;
|
||||||
|
|
||||||
|
QmlGeod* geod() const;
|
||||||
|
|
||||||
|
double navaidFrequencyMHz() const;
|
||||||
|
double navaidRangeNm() const;
|
||||||
|
|
||||||
|
QmlPositioned* navaidRunway() const;
|
||||||
|
QmlPositioned* colocatedDME() const;
|
||||||
|
|
||||||
|
// owning airport if one exists
|
||||||
|
QmlPositioned* owningAirport() const;
|
||||||
|
|
||||||
|
double runwayHeadingDeg() const;
|
||||||
|
double runwayLengthFt() const;
|
||||||
|
|
||||||
|
Q_INVOKABLE bool equals(QmlPositioned* other) const;
|
||||||
|
|
||||||
|
bool airportHasParkings() const;
|
||||||
|
|
||||||
|
public slots:
|
||||||
|
void setGuid(qlonglong guid);
|
||||||
|
|
||||||
|
signals:
|
||||||
|
void guidChanged();
|
||||||
|
void infoChanged();
|
||||||
|
|
||||||
|
private:
|
||||||
|
FGPositionedRef m_pos;
|
||||||
|
};
|
||||||
|
|
||||||
|
bool operator==(const QmlPositioned& p1, const QmlPositioned& p2);
|
||||||
|
|
||||||
|
#endif // QMLPOSITIONED_HXX
|
|
@ -1,15 +1,11 @@
|
||||||
#ifndef QTGUI_FWD_H
|
#ifndef QTGUI_FWD_H
|
||||||
#define QTGUI_FWD_H
|
#define QTGUI_FWD_H
|
||||||
|
|
||||||
enum LauncherAircraftType
|
#include <QString>
|
||||||
{
|
|
||||||
Airplane = 0,
|
|
||||||
Seaplane,
|
|
||||||
Helicopter,
|
|
||||||
Airship
|
|
||||||
};
|
|
||||||
|
|
||||||
extern QString fixNavaidName(QString s);
|
extern QString fixNavaidName(QString s);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
#endif // QTGUI_FWD_H
|
#endif // QTGUI_FWD_H
|
||||||
|
|
||||||
|
|
|
@ -15,6 +15,7 @@ FocusScope {
|
||||||
property alias prefix: prefix.text
|
property alias prefix: prefix.text
|
||||||
property alias maxDigits: edit.maximumLength
|
property alias maxDigits: edit.maximumLength
|
||||||
property int step: 1
|
property int step: 1
|
||||||
|
property bool live: false
|
||||||
|
|
||||||
implicitHeight: editFrame.height
|
implicitHeight: editFrame.height
|
||||||
// we have a margin between the frame and the label, and on each
|
// we have a margin between the frame and the label, and on each
|
||||||
|
@ -25,8 +26,11 @@ FocusScope {
|
||||||
function incrementValue()
|
function incrementValue()
|
||||||
{
|
{
|
||||||
if (edit.activeFocus) {
|
if (edit.activeFocus) {
|
||||||
value = Math.min(parseFloat(edit.text) + root.step, root.max)
|
var newValue = Math.min(parseFloat(edit.text) + root.step, root.max)
|
||||||
edit.text = value
|
edit.text = newValue
|
||||||
|
if (live) {
|
||||||
|
commit(newValue);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
commit(Math.min(value + root.step, root.max))
|
commit(Math.min(value + root.step, root.max))
|
||||||
}
|
}
|
||||||
|
@ -35,8 +39,11 @@ FocusScope {
|
||||||
function decrementValue()
|
function decrementValue()
|
||||||
{
|
{
|
||||||
if (edit.activeFocus) {
|
if (edit.activeFocus) {
|
||||||
value = Math.max(parseFloat(edit.text) - root.step, root.min)
|
var newValue = Math.max(parseFloat(edit.text) - root.step, root.min)
|
||||||
edit.text = value
|
edit.text = newValue
|
||||||
|
if (live) {
|
||||||
|
commit(newValue);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
commit(Math.max(value - root.step, root.min))
|
commit(Math.max(value - root.step, root.min))
|
||||||
}
|
}
|
||||||
|
@ -75,6 +82,17 @@ FocusScope {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// timer to commit the value when in live mode
|
||||||
|
Timer {
|
||||||
|
id: liveEditTimer
|
||||||
|
interval: 800
|
||||||
|
onTriggered: {
|
||||||
|
if (edit.activeFocus) {
|
||||||
|
commit(parseInt(edit.text));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Binding {
|
Binding {
|
||||||
when: !edit.activeFocus
|
when: !edit.activeFocus
|
||||||
target: edit
|
target: edit
|
||||||
|
@ -133,6 +151,13 @@ FocusScope {
|
||||||
selectAll();
|
selectAll();
|
||||||
} else {
|
} else {
|
||||||
commit(parseFloat(text))
|
commit(parseFloat(text))
|
||||||
|
liveEditTimer.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onTextChanged: {
|
||||||
|
if (activeFocus && root.live) {
|
||||||
|
liveEditTimer.restart();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -13,6 +13,7 @@ FocusScope {
|
||||||
property alias prefix: prefix.text
|
property alias prefix: prefix.text
|
||||||
property alias maxDigits: edit.maximumLength
|
property alias maxDigits: edit.maximumLength
|
||||||
property int step: 1
|
property int step: 1
|
||||||
|
property bool live: false
|
||||||
|
|
||||||
implicitHeight: editFrame.height
|
implicitHeight: editFrame.height
|
||||||
// we have a margin between the frame and the label, and on each
|
// we have a margin between the frame and the label, and on each
|
||||||
|
@ -23,8 +24,11 @@ FocusScope {
|
||||||
function incrementValue()
|
function incrementValue()
|
||||||
{
|
{
|
||||||
if (edit.activeFocus) {
|
if (edit.activeFocus) {
|
||||||
value = Math.min(parseInt(edit.text) + root.step, root.max)
|
var newValue = Math.min(parseInt(edit.text) + root.step, root.max)
|
||||||
edit.text = value
|
edit.text = newValue
|
||||||
|
if (live) {
|
||||||
|
commit(newValue);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
commit(Math.min(value + root.step, root.max))
|
commit(Math.min(value + root.step, root.max))
|
||||||
}
|
}
|
||||||
|
@ -33,8 +37,11 @@ FocusScope {
|
||||||
function decrementValue()
|
function decrementValue()
|
||||||
{
|
{
|
||||||
if (edit.activeFocus) {
|
if (edit.activeFocus) {
|
||||||
value = Math.max(parseInt(edit.text) - root.step, root.min)
|
var newValue = Math.max(parseInt(edit.text) - root.step, root.min)
|
||||||
edit.text = value
|
edit.text = newValue
|
||||||
|
if (live) {
|
||||||
|
commit(newValue);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
commit(Math.max(value - root.step, root.min))
|
commit(Math.max(value - root.step, root.min))
|
||||||
}
|
}
|
||||||
|
@ -73,6 +80,17 @@ FocusScope {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// timer to commit the value when in live mode
|
||||||
|
Timer {
|
||||||
|
id: liveEditTimer
|
||||||
|
interval: 800
|
||||||
|
onTriggered: {
|
||||||
|
if (edit.activeFocus) {
|
||||||
|
commit(parseInt(edit.text));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Binding {
|
Binding {
|
||||||
when: !edit.activeFocus
|
when: !edit.activeFocus
|
||||||
target: edit
|
target: edit
|
||||||
|
@ -131,6 +149,13 @@ FocusScope {
|
||||||
selectAll();
|
selectAll();
|
||||||
} else {
|
} else {
|
||||||
commit(parseInt(text))
|
commit(parseInt(text))
|
||||||
|
liveEditTimer.stop();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
onTextChanged: {
|
||||||
|
if (activeFocus && root.live) {
|
||||||
|
liveEditTimer.restart();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
248
src/GUI/qml/Location.qml
Normal file
248
src/GUI/qml/Location.qml
Normal file
|
@ -0,0 +1,248 @@
|
||||||
|
import QtQuick 2.4
|
||||||
|
import FlightGear 1.0
|
||||||
|
import FlightGear.Launcher 1.0
|
||||||
|
import "."
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
|
||||||
|
property bool __searchActive: false
|
||||||
|
property string lastSearch
|
||||||
|
|
||||||
|
function backToSearch()
|
||||||
|
{
|
||||||
|
detailLoader.sourceComponent = null
|
||||||
|
}
|
||||||
|
|
||||||
|
function selectLocation(guid, type)
|
||||||
|
{
|
||||||
|
selectedLocation.guid = guid;
|
||||||
|
_location.setBaseLocation(selectedLocation)
|
||||||
|
_location.addToRecent(selectedLocation);
|
||||||
|
|
||||||
|
if (selectedLocation.isAirportType) {
|
||||||
|
detailLoader.sourceComponent = airportDetails
|
||||||
|
} else {
|
||||||
|
detailLoader.sourceComponent = navaidDetails
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
_location.showHistoryInSearchModel()
|
||||||
|
}
|
||||||
|
|
||||||
|
Positioned {
|
||||||
|
id: selectedLocation
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: airportDetails
|
||||||
|
LocationAirportView {
|
||||||
|
id: airportView
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: navaidDetails
|
||||||
|
LocationNavaidView {
|
||||||
|
id: navaidView
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
anchors.fill: parent
|
||||||
|
color: "white"
|
||||||
|
}
|
||||||
|
|
||||||
|
Component {
|
||||||
|
id: locationSearchDelegate
|
||||||
|
Rectangle {
|
||||||
|
id: delegateRoot
|
||||||
|
height: delegateContent.height + Style.margin
|
||||||
|
width: searchView.width
|
||||||
|
|
||||||
|
function itemDescription()
|
||||||
|
{
|
||||||
|
if (model.type === Positioned.Fix) return model.ident
|
||||||
|
|
||||||
|
if (model.type === Positioned.VOR) {
|
||||||
|
var freq = (model.frequency / 100).toFixed(3);
|
||||||
|
return "%1 - %2 (%3 MHz)".arg(model.ident).arg(model.name).arg(freq);
|
||||||
|
}
|
||||||
|
|
||||||
|
// general case
|
||||||
|
return "%1 - %2".arg(model.ident).arg(model.name);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: delegateContent
|
||||||
|
height: Math.max(delegateIcon.height, delegateText.height)
|
||||||
|
width: parent.width
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
visible: delegateMouse.containsMouse
|
||||||
|
color: "#cfcfcf"
|
||||||
|
}
|
||||||
|
|
||||||
|
PixmapImage {
|
||||||
|
id: delegateIcon
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.leftMargin: Style.margin
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
image: model.icon
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
id: delegateText
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.left: delegateIcon.right
|
||||||
|
anchors.rightMargin: Style.margin
|
||||||
|
anchors.leftMargin: Style.margin
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
text: delegateRoot.itemDescription();
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
}
|
||||||
|
|
||||||
|
MouseArea {
|
||||||
|
id: delegateMouse
|
||||||
|
anchors.fill: parent
|
||||||
|
hoverEnabled: true
|
||||||
|
onClicked: {
|
||||||
|
root.selectLocation(model.guid, model.type);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: footer
|
||||||
|
height: Style.margin
|
||||||
|
width: parent.width
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
color: Style.frameColor
|
||||||
|
height: 1
|
||||||
|
width: parent.width - Style.strutSize
|
||||||
|
anchors.centerIn: parent
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SearchButton {
|
||||||
|
id: searchButton
|
||||||
|
|
||||||
|
anchors.right: parent.right
|
||||||
|
anchors.top: parent.top
|
||||||
|
anchors.left: parent.left
|
||||||
|
anchors.margins: Style.margin
|
||||||
|
|
||||||
|
autoSubmit: false
|
||||||
|
placeholder: qsTr("Enter a navaid or airport ID, name or a latitude & longitude");
|
||||||
|
|
||||||
|
onSearch: {
|
||||||
|
// when th search term is cleared, show the history
|
||||||
|
if (term == "") {
|
||||||
|
_location.showHistoryInSearchModel();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var geod = _location.parseStringAsGeod(term)
|
||||||
|
if (geod.valid) {
|
||||||
|
console.info("REMOVE-ME: Setting lat-lon location")
|
||||||
|
_location.baseGeod = geod
|
||||||
|
selectedLocation.guid = 0;
|
||||||
|
detailLoader.sourceComponent = navaidDetails
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
root.lastSearch = term;
|
||||||
|
_location.searchModel.setSearch(term, _launcher.aircraftType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: headerSplit
|
||||||
|
color: Style.frameColor
|
||||||
|
height: 1
|
||||||
|
width: parent.width - Style.inset
|
||||||
|
anchors.horizontalCenter: parent.horizontalCenter
|
||||||
|
anchors.top: searchButton.bottom
|
||||||
|
anchors.topMargin: Style.margin
|
||||||
|
}
|
||||||
|
|
||||||
|
ListView {
|
||||||
|
id: searchView
|
||||||
|
anchors.top: headerSplit.bottom
|
||||||
|
anchors.topMargin: Style.margin
|
||||||
|
width: parent.width
|
||||||
|
anchors.bottom: parent.bottom
|
||||||
|
model: _location.searchModel
|
||||||
|
delegate: locationSearchDelegate
|
||||||
|
clip: true
|
||||||
|
|
||||||
|
header: Item {
|
||||||
|
visible: _location.searchModel.isSearchActive
|
||||||
|
width: parent.width
|
||||||
|
height: visible ? 50 : 0
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: qsTr("Searching")
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.right: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
AnimatedImage {
|
||||||
|
source: "qrc://linear-spinner"
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
anchors.left: parent.horizontalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
footer: Item {
|
||||||
|
width: parent.width
|
||||||
|
height: noResultsText.height
|
||||||
|
visible: (parent.count === 0) && !_location.searchModel.isSearchActive
|
||||||
|
Text {
|
||||||
|
id: noResultsText
|
||||||
|
width: parent.width
|
||||||
|
text: qsTr("No results for found search '%1'").arg(root.lastSearch)
|
||||||
|
wrapMode: Text.WordWrap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// scrollbar
|
||||||
|
|
||||||
|
Loader {
|
||||||
|
id: detailLoader
|
||||||
|
anchors.fill: parent
|
||||||
|
visible: sourceComponent != null
|
||||||
|
|
||||||
|
onStatusChanged: {
|
||||||
|
if (status == Loader.Ready) {
|
||||||
|
if (selectedLocation.valid) {
|
||||||
|
item.location = selectedLocation.guid
|
||||||
|
} else {
|
||||||
|
// lon-lat
|
||||||
|
item.geod = _location.baseGeod
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Button {
|
||||||
|
anchors { left: parent.left; top: parent.top; margins: Style.margin }
|
||||||
|
width: Style.strutSize
|
||||||
|
visible: detailLoader.visible
|
||||||
|
|
||||||
|
id: backButton
|
||||||
|
text: "< Back"
|
||||||
|
onClicked: {
|
||||||
|
root.backToSearch();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
278
src/GUI/qml/LocationAirportView.qml
Normal file
278
src/GUI/qml/LocationAirportView.qml
Normal file
|
@ -0,0 +1,278 @@
|
||||||
|
import QtQuick 2.4
|
||||||
|
import FlightGear 1.0
|
||||||
|
import FlightGear.Launcher 1.0
|
||||||
|
import "."
|
||||||
|
|
||||||
|
Item {
|
||||||
|
id: root
|
||||||
|
property alias location: airportData.guid
|
||||||
|
|
||||||
|
Positioned {
|
||||||
|
id: airportData
|
||||||
|
onGuidChanged: _location.setBaseLocation(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
readonly property bool isHeliport: airportData.type === Positioned.Heliport
|
||||||
|
readonly property bool haveParking: airportData.airportHasParkings
|
||||||
|
|
||||||
|
AirportDiagram {
|
||||||
|
id: diagram
|
||||||
|
anchors.fill: parent
|
||||||
|
airport: airportData.guid
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
if (pos === null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
_location.setDetailLocation(pos)
|
||||||
|
diagram.selection = pos
|
||||||
|
syncUIFromController();
|
||||||
|
}
|
||||||
|
|
||||||
|
approachExtensionNm: _location.onFinal ? _location.offsetNm : -1.0
|
||||||
|
}
|
||||||
|
|
||||||
|
// not very declarative, try to remove this over time
|
||||||
|
function syncUIFromController()
|
||||||
|
{
|
||||||
|
runwayRadio.selected = (_location.detail.isRunwayType);
|
||||||
|
parkingRadio.selected = (_location.detail.type == Positioned.Parking);
|
||||||
|
|
||||||
|
if (_location.detail.isRunwayType) {
|
||||||
|
runwayChoice.syncCurrentIndex();
|
||||||
|
} else if (_location.detail.type == Positioned.Parking) {
|
||||||
|
parkingChoice.syncCurrentIndex();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
RadioButtonGroup {
|
||||||
|
id: radioGroup
|
||||||
|
}
|
||||||
|
|
||||||
|
Component.onCompleted: {
|
||||||
|
syncUIFromController();
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: panel
|
||||||
|
|
||||||
|
color: "transparent"
|
||||||
|
border.width: 1
|
||||||
|
border.color: Style.frameColor
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
bottom: parent.bottom
|
||||||
|
margins: Style.strutSize
|
||||||
|
}
|
||||||
|
|
||||||
|
height: selectionGrid.height + Style.margin * 2
|
||||||
|
|
||||||
|
// set opacity here only, so we don't make the whole summary pannel translucent
|
||||||
|
Rectangle {
|
||||||
|
id: background
|
||||||
|
anchors.fill: parent
|
||||||
|
z: -1
|
||||||
|
opacity: Style.panelOpacity
|
||||||
|
color: "white"
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: selectionGrid
|
||||||
|
spacing: Style.margin
|
||||||
|
width: parent.width
|
||||||
|
|
||||||
|
Text { // heading text
|
||||||
|
id: airportHeading
|
||||||
|
width: parent.width
|
||||||
|
text: isHeliport ? qsTr("Heliport: ") + airportData.ident + " / " + airportData.name
|
||||||
|
: qsTr("Airport: ") + airportData.ident + " / " + airportData.name
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
width: parent.width
|
||||||
|
spacing: Style.margin
|
||||||
|
|
||||||
|
RadioButton {
|
||||||
|
id: runwayRadio
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
group: radioGroup
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
if (selected) runwayChoice.setLocation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: isHeliport ? qsTr("Pad") : qsTr("Runway")
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
PopupChoice {
|
||||||
|
id: runwayChoice
|
||||||
|
model: _location.airportRunways
|
||||||
|
displayRole: "ident"
|
||||||
|
width: parent.width * 0.5
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
headerText: qsTr("Active")
|
||||||
|
enabled: runwayRadio.selected
|
||||||
|
|
||||||
|
onCurrentIndexChanged: {
|
||||||
|
setLocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
function setLocation()
|
||||||
|
{
|
||||||
|
if (currentIndex == -1) {
|
||||||
|
_location.useActiveRunway = true;
|
||||||
|
diagram.selection = null;
|
||||||
|
} else {
|
||||||
|
_location.setDetailLocation(_location.airportRunways[currentIndex])
|
||||||
|
diagram.selection = _location.airportRunways[currentIndex]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function syncCurrentIndex()
|
||||||
|
{
|
||||||
|
if (_location.useActiveRunway) {
|
||||||
|
currentIndex = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i=0; i < _location.airportRunways.length; ++i) {
|
||||||
|
if (_location.airportRunways[i].equals(_location.detail)) {
|
||||||
|
currentIndex = i;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// not found, default to active
|
||||||
|
currentIndex = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// runway offset row
|
||||||
|
Row {
|
||||||
|
x: Style.strutSize
|
||||||
|
|
||||||
|
// no offset for helipads
|
||||||
|
visible: !isHeliport
|
||||||
|
|
||||||
|
ToggleSwitch {
|
||||||
|
id: onFinalToggle
|
||||||
|
label: qsTr("On final approach at ")
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
checked: _location.onFinal
|
||||||
|
enabled:runwayRadio.selected
|
||||||
|
onCheckedChanged: _location.onFinal = checked
|
||||||
|
}
|
||||||
|
|
||||||
|
DoubleSpinbox {
|
||||||
|
id: offsetNmEdit
|
||||||
|
value: _location.offsetNm
|
||||||
|
onCommit: _location.offsetNm = newValue;
|
||||||
|
|
||||||
|
suffix: "Nm"
|
||||||
|
min: 0.0
|
||||||
|
max: 40.0
|
||||||
|
decimals: 1
|
||||||
|
maxDigits: 5
|
||||||
|
live: true
|
||||||
|
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
enabled: runwayRadio.selected && onFinalToggle.checked
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: qsTr(" from the threshold")
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ToggleSwitch {
|
||||||
|
x: Style.strutSize
|
||||||
|
// no localizer for helipads
|
||||||
|
visible: !isHeliport
|
||||||
|
|
||||||
|
// enable if selected runway has ILS
|
||||||
|
label: qsTr("Tune navigation radio (NAV1) to runway localizer")
|
||||||
|
checked: _location.tuneNAV1
|
||||||
|
|
||||||
|
onCheckedChanged: {
|
||||||
|
_location.tuneNAV1 = checked
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// parking row
|
||||||
|
Row {
|
||||||
|
width: parent.width
|
||||||
|
spacing: Style.margin
|
||||||
|
|
||||||
|
// hide if there's no parking locations defined for this airport
|
||||||
|
visible: haveParking
|
||||||
|
|
||||||
|
RadioButton {
|
||||||
|
id: parkingRadio
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
group: radioGroup
|
||||||
|
|
||||||
|
onClicked: {
|
||||||
|
if (selected) parkingChoice.setLocation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: qsTr("Parking")
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
PopupChoice {
|
||||||
|
id: parkingChoice
|
||||||
|
model: _location.airportParkings
|
||||||
|
displayRole: "name"
|
||||||
|
width: parent.width * 0.5
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
headerText: qsTr("Available")
|
||||||
|
enabled: parkingRadio.selected
|
||||||
|
|
||||||
|
onCurrentIndexChanged: {
|
||||||
|
setLocation();
|
||||||
|
}
|
||||||
|
|
||||||
|
function syncCurrentIndex()
|
||||||
|
{
|
||||||
|
if (_location.useAvailableParking) {
|
||||||
|
currentIndex = -1;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i=0; i < _location.airportParkings.length; ++i) {
|
||||||
|
if (_location.airportParkings[i].equals(_location.detail)) {
|
||||||
|
currentIndex = i;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// not found, default to available
|
||||||
|
currentIndex = -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
function setLocation()
|
||||||
|
{
|
||||||
|
if (currentIndex == -1) {
|
||||||
|
_location.useAvailableParking = true;
|
||||||
|
diagram.selection = null;
|
||||||
|
} else {
|
||||||
|
_location.setDetailLocation(_location.airportParkings[currentIndex])
|
||||||
|
diagram.selection = _location.airportParkings[currentIndex]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
} // main layout column
|
||||||
|
} // main panel rectangle
|
||||||
|
}
|
182
src/GUI/qml/LocationNavaidView.qml
Normal file
182
src/GUI/qml/LocationNavaidView.qml
Normal file
|
@ -0,0 +1,182 @@
|
||||||
|
import QtQuick 2.4
|
||||||
|
import FlightGear 1.0
|
||||||
|
import FlightGear.Launcher 1.0
|
||||||
|
import "."
|
||||||
|
|
||||||
|
Item {
|
||||||
|
property alias location: navaidData.guid
|
||||||
|
property alias geod: diagram.geod
|
||||||
|
|
||||||
|
Positioned {
|
||||||
|
id: navaidData
|
||||||
|
onGuidChanged: {
|
||||||
|
if (guid > 0) {
|
||||||
|
diagram.navaid = guid
|
||||||
|
_location.setBaseLocation(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
NavaidDiagram {
|
||||||
|
id: diagram
|
||||||
|
anchors.fill: parent
|
||||||
|
|
||||||
|
offsetEnabled: _location.offsetEnabled
|
||||||
|
offsetBearingDeg: _location.offsetRadial
|
||||||
|
offsetDistanceNm: _location.offsetNm
|
||||||
|
headingDeg: _location.headingDeg
|
||||||
|
}
|
||||||
|
|
||||||
|
Rectangle {
|
||||||
|
id: panel
|
||||||
|
|
||||||
|
color: "transparent"
|
||||||
|
border.width: 1
|
||||||
|
border.color: Style.frameColor
|
||||||
|
|
||||||
|
anchors {
|
||||||
|
left: parent.left
|
||||||
|
right: parent.right
|
||||||
|
bottom: parent.bottom
|
||||||
|
margins: Style.strutSize
|
||||||
|
}
|
||||||
|
|
||||||
|
height: selectionGrid.height + Style.margin * 2
|
||||||
|
|
||||||
|
// set opacity here only, so we don't make the whole summary pannel translucent
|
||||||
|
Rectangle {
|
||||||
|
id: background
|
||||||
|
anchors.fill: parent
|
||||||
|
z: -1
|
||||||
|
opacity: Style.panelOpacity
|
||||||
|
color: "white"
|
||||||
|
}
|
||||||
|
|
||||||
|
Column {
|
||||||
|
id: selectionGrid
|
||||||
|
spacing: Style.margin
|
||||||
|
width: parent.width
|
||||||
|
|
||||||
|
Text { // heading text
|
||||||
|
visible: navaidData.valid
|
||||||
|
id: heading
|
||||||
|
width: parent.width
|
||||||
|
text: "Navaid: " + navaidData.ident + " / " + navaidData.name
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
height: childrenRect.height
|
||||||
|
width: parent.width
|
||||||
|
spacing: Style.margin
|
||||||
|
|
||||||
|
IntegerSpinbox {
|
||||||
|
label: qsTr("Airspeed:")
|
||||||
|
suffix: "kts"
|
||||||
|
min: 0
|
||||||
|
max: 10000 // more for spaceships?
|
||||||
|
step: 5
|
||||||
|
maxDigits: 5
|
||||||
|
value: _location.airspeedKnots
|
||||||
|
onCommit: _location.airspeedKnots = newValue
|
||||||
|
}
|
||||||
|
|
||||||
|
IntegerSpinbox {
|
||||||
|
label: qsTr("Heading:")
|
||||||
|
suffix: "deg" // FIXME use Unicode degree symbol
|
||||||
|
min: 0
|
||||||
|
max: 359
|
||||||
|
live: true
|
||||||
|
maxDigits: 3
|
||||||
|
value: _location.headingDeg
|
||||||
|
onCommit: _location.headingDeg = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Row {
|
||||||
|
height: childrenRect.height
|
||||||
|
width: parent.width
|
||||||
|
spacing: Style.margin
|
||||||
|
|
||||||
|
IntegerSpinbox {
|
||||||
|
label: qsTr("Altitude:")
|
||||||
|
suffix: "ft"
|
||||||
|
min: -1000 // Dead Sea, Schiphol
|
||||||
|
max: 200000
|
||||||
|
step: 100
|
||||||
|
maxDigits: 6
|
||||||
|
|
||||||
|
visible: !altitudeTypeChoice.isFlightLevel
|
||||||
|
value: _location.altitudeFt
|
||||||
|
onCommit: _location.altitudeFt = newValue
|
||||||
|
}
|
||||||
|
|
||||||
|
IntegerSpinbox {
|
||||||
|
label: qsTr("Altitude:")
|
||||||
|
prefix: "FL"
|
||||||
|
min: 0
|
||||||
|
max: 1000
|
||||||
|
step: 10
|
||||||
|
maxDigits: 3
|
||||||
|
visible: altitudeTypeChoice.isFlightLevel
|
||||||
|
}
|
||||||
|
|
||||||
|
PopupChoice {
|
||||||
|
id: altitudeTypeChoice
|
||||||
|
|
||||||
|
readonly property bool isFlightLevel: (currentIndex == 2)
|
||||||
|
|
||||||
|
model: [qsTr("Above mean sea-level (MSL)"),
|
||||||
|
qsTr("Above ground (AGL)"),
|
||||||
|
qsTr("Flight-level")]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// offset row
|
||||||
|
Row {
|
||||||
|
x: Style.strutSize
|
||||||
|
|
||||||
|
ToggleSwitch {
|
||||||
|
id: offsetToggle
|
||||||
|
label: qsTr("Offset ")
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
checked: _location.offsetEnabled
|
||||||
|
onCheckedChanged: {
|
||||||
|
_location.offsetEnabled = checked
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DoubleSpinbox {
|
||||||
|
id: offsetNmEdit
|
||||||
|
value: _location.offsetNm
|
||||||
|
onCommit: _location.offsetNm = newValue
|
||||||
|
min: 0.0
|
||||||
|
max: 40.0
|
||||||
|
suffix: "Nm"
|
||||||
|
maxDigits: 5
|
||||||
|
decimals: 1
|
||||||
|
live: true
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
enabled: offsetToggle.checked
|
||||||
|
}
|
||||||
|
|
||||||
|
Text {
|
||||||
|
text: qsTr(" on bearing ")
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
}
|
||||||
|
|
||||||
|
IntegerSpinbox {
|
||||||
|
id: offsetBearingEdit
|
||||||
|
suffix: "deg" // FIXME use Unicode degree symbol
|
||||||
|
min: 0
|
||||||
|
max: 359
|
||||||
|
maxDigits: 3
|
||||||
|
live: true
|
||||||
|
anchors.verticalCenter: parent.verticalCenter
|
||||||
|
enabled: offsetToggle.checked
|
||||||
|
value: _location.offsetRadial
|
||||||
|
onCommit: _location.offsetRadial = newValue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} // main layout column
|
||||||
|
} // main panel rectangle
|
||||||
|
}
|
|
@ -18,6 +18,13 @@ Item {
|
||||||
color: "magenta"
|
color: "magenta"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Connections {
|
||||||
|
target: _launcher
|
||||||
|
onAircraftTypeChanged: {
|
||||||
|
console.info("Aircraft type is now:" + _launcher.aircraftType)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
PreviewImage {
|
PreviewImage {
|
||||||
id: preview
|
id: preview
|
||||||
anchors.centerIn: parent
|
anchors.centerIn: parent
|
||||||
|
@ -151,7 +158,8 @@ Item {
|
||||||
// TODO - make clickable, jump to to the aircraft in the installed
|
// TODO - make clickable, jump to to the aircraft in the installed
|
||||||
// aircraft list
|
// aircraft list
|
||||||
Text {
|
Text {
|
||||||
text: _launcher.selectedAircraftInfo.name
|
text: _launcher.selectedAircraftInfo.name === "" ?
|
||||||
|
qsTr("No aircraft selected") : _launcher.selectedAircraftInfo.name
|
||||||
font.pixelSize: Style.headingFontPixelSize
|
font.pixelSize: Style.headingFontPixelSize
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -265,8 +273,9 @@ Item {
|
||||||
|
|
||||||
// TODO - make clickable, jump to the location page
|
// TODO - make clickable, jump to the location page
|
||||||
Text {
|
Text {
|
||||||
text: _launcher.locationDescription
|
text: _launcher.location.description
|
||||||
font.pixelSize: Style.headingFontPixelSize
|
font.pixelSize: Style.headingFontPixelSize
|
||||||
|
width: summaryGrid.middleColumnWidth
|
||||||
}
|
}
|
||||||
|
|
||||||
HistoryPopup {
|
HistoryPopup {
|
||||||
|
|
|
@ -72,6 +72,7 @@
|
||||||
<file>qml/DateTimeValueEdit.qml</file>
|
<file>qml/DateTimeValueEdit.qml</file>
|
||||||
<file>qml/SettingsDateTimePicker.qml</file>
|
<file>qml/SettingsDateTimePicker.qml</file>
|
||||||
<file>qml/Summary.qml</file>
|
<file>qml/Summary.qml</file>
|
||||||
|
<file>qml/Location.qml</file>
|
||||||
<file>qml/HistoryPopup.qml</file>
|
<file>qml/HistoryPopup.qml</file>
|
||||||
<file>qml/AddOns.qml</file>
|
<file>qml/AddOns.qml</file>
|
||||||
<file>qml/DragToReorderButton.qml</file>
|
<file>qml/DragToReorderButton.qml</file>
|
||||||
|
@ -86,6 +87,8 @@
|
||||||
<file>qml/PathListDelegate.qml</file>
|
<file>qml/PathListDelegate.qml</file>
|
||||||
<file>qml/AddCatalogPanel.qml</file>
|
<file>qml/AddCatalogPanel.qml</file>
|
||||||
<file>qml/LineEdit.qml</file>
|
<file>qml/LineEdit.qml</file>
|
||||||
|
<file>qml/LocationAirportView.qml</file>
|
||||||
|
<file>qml/LocationNavaidView.qml</file>
|
||||||
<file alias="linear-spinner">qml/icons8-linear-spinner.gif</file>
|
<file alias="linear-spinner">qml/icons8-linear-spinner.gif</file>
|
||||||
<file>qml/RadioButton.qml</file>
|
<file>qml/RadioButton.qml</file>
|
||||||
<file>qml/IntegerSpinbox.qml</file>
|
<file>qml/IntegerSpinbox.qml</file>
|
||||||
|
|
Loading…
Reference in a new issue