]> git.mxchange.org Git - flightgear.git/commitdiff
Fix selection of parking positions by clicking.
authorJames Turner <zakalawe@mac.com>
Sat, 16 Jul 2016 15:57:19 +0000 (16:57 +0100)
committerRoland Haeder <roland@mxchange.org>
Thu, 22 Sep 2016 21:27:47 +0000 (23:27 +0200)
src/GUI/AirportDiagram.cxx
src/GUI/AirportDiagram.hxx

index 6f33a82fbafa6f5b6ceac332da19faa98d447cb8..2d016b927e1438e9ec9f0ab1115dec21ac81ddd9 100644 (file)
@@ -82,7 +82,8 @@ static double distanceToLineSegment(const QVector2D& p, const QVector2D& a,
 
 AirportDiagram::AirportDiagram(QWidget* pr) :
     BaseDiagram(pr),
-    m_approachDistanceNm(-1.0)
+    m_approachDistanceNm(-1.0),
+    m_helipadIcon(":/heliport-icon")
 {
     m_parkingIconPath.moveTo(0,0);
     m_parkingIconPath.lineTo(-16, -16);
@@ -158,6 +159,10 @@ void AirportDiagram::setSelectedParking(FGParkingRef park)
 
 void AirportDiagram::setApproachExtensionDistance(double distanceNm)
 {
+    if (m_approachDistanceNm == distanceNm) {
+        return;
+    }
+
     m_approachDistanceNm = distanceNm;
     recomputeBounds(true);
     update();
@@ -335,15 +340,14 @@ void AirportDiagram::paintContents(QPainter* p)
 void AirportDiagram::drawHelipads(QPainter* painter)
 {
     QTransform t = painter->transform();
-    QPixmap icon(":/heliport-icon");
 
-    QRect r = icon.rect();
+    QRect r = m_helipadIcon.rect();
     r.moveCenter(QPoint(0, 0));
 
     Q_FOREACH(const HelipadData& p, m_helipads) {
         painter->setTransform(t);
         painter->translate(p.pt);
-        painter->drawPixmap(r, icon);
+        painter->drawPixmap(r, m_helipadIcon);
     }
 }
 
@@ -446,67 +450,89 @@ void AirportDiagram::drawILS(QPainter* painter, FGRunwayRef runway) const
     painter->drawLine(endR, endCentre);
 }
 
-static double pointDistance(const QPointF& p1, const QPointF& p2)
-{
-    QPointF d = p2 - p1;
-    return ::sqrt((d.x() * d.x()) + (d.y() * d.y()));
-}
-
 void AirportDiagram::mouseReleaseEvent(QMouseEvent* me)
 {
-    if (m_didPan)
-        return; // ignore panning drag+release ops here
+    if (me->button() != Qt::LeftButton) {
+        return;
+    }
 
     QTransform t(transform());
-    double minDist = std::numeric_limits<double>::max();
-    FGRunwayRef bestRunway;
-    FGHelipadRef bestHelipad;
-    FGParkingRef bestParking;
-
     Q_FOREACH(const RunwayData& r, m_runways) {
-        QPointF p1(t.map(r.p1)), p2(t.map(r.p2));
-        double t;
-        double d = distanceToLineSegment(QVector2D(me->pos()),
-                                         QVector2D(p1),
-                                         QVector2D(p2), &t);
-        if (d < minDist) {
-            if (t > 0.5) {
-                bestRunway = r.runway->reciprocalRunway();
+        QPainterPath pp = pathForRunway(r, t);
+        if (pp.contains(me->pos())) {
+            // check which end was clicked
+            QPointF p1(t.map(r.p1)), p2(t.map(r.p2));
+            double param;
+            distanceToLineSegment(QVector2D(me->pos()), QVector2D(p1), QVector2D(p2), &param);
+            if (param > 0.5) {
+                emit clickedRunway(r.runway->reciprocalRunway());
             } else {
-                bestRunway = r.runway;
+                emit clickedRunway(r.runway);
             }
-            minDist = d;
+            return;
         }
-    }
+    } // of runways iteration
 
     Q_FOREACH(const ParkingData& parking, m_parking) {
-        double d = pointDistance(me->pos(), t.map(parking.pt));
-        if (d < minDist) {
-            bestParking = parking.parking;
-            bestRunway.clear();
-            minDist = d;
+        QPainterPath pp = pathForParking(parking, t);
+        if (pp.contains(me->pos())) {
+            emit clickedParking(parking.parking);
+            return;
         }
     }
 
+
     Q_FOREACH(const HelipadData& pad, m_helipads) {
-        double d = pointDistance(me->pos(), t.map(pad.pt));
-        if (d < minDist) {
-            bestHelipad = pad.helipad;
-            bestRunway.clear();
-            bestParking.clear();
-            minDist = d;
+        QPainterPath pp = pathForHelipad(pad, t);
+        if (pp.contains(me->pos())) {
+            emit clickedHelipad(pad.helipad);
+            return;
         }
     }
+}
 
-    
-    if (minDist < 16.0) {
-        if (bestRunway)
-            emit clickedRunway(bestRunway);
-        else if (bestParking)
-            emit clickedParking(bestParking);
-        else if (bestHelipad)
-            emit clickedHelipad(bestHelipad);
+QPainterPath AirportDiagram::pathForRunway(const RunwayData& r, const QTransform& t) const
+{
+    QPainterPath pp;
+    double halfWidth = r.widthM * 0.5;
+    QVector2D v = QVector2D(r.p2 - r.p1);
+    v.normalize();
+    QVector2D halfVec = QVector2D(v.y(), -v.x()) * halfWidth;
+
+    pp.moveTo(r.p1 - halfVec.toPointF());
+    pp.lineTo(r.p1 + halfVec.toPointF());
+    pp.lineTo(r.p2 + halfVec.toPointF());
+    pp.lineTo(r.p2 - halfVec.toPointF());
+    pp.closeSubpath();
+
+    return t.map(pp);
+}
+
+QPainterPath AirportDiagram::pathForParking(const ParkingData& p, const QTransform& t) const
+{
+    bool useLeftIcon = false;
+    double hdg = p.parking->getHeading();
+
+    if (hdg > 180.0) {
+        hdg += 90;
+        useLeftIcon = true;
+    } else {
+        hdg -= 90;
     }
+
+    QTransform x = t;
+    x.translate(p.pt.x(), p.pt.y());
+    x.rotate(hdg);
+    return x.map(useLeftIcon ? m_parkingIconLeftPath : m_parkingIconPath);
+}
+
+QPainterPath AirportDiagram::pathForHelipad(const HelipadData& h, const QTransform& t) const
+{
+    QPainterPath pp;
+    QRect r = m_helipadIcon.rect();
+    r.moveCenter(QPoint(0, 0));
+    pp.addEllipse(r);
+    return t.map(pp);
 }
 
 void AirportDiagram::buildTaxiways()
index 4778811003736f8d53e1100f615aa134214dd812..101da6258d7858e97a4fe841a65fbd12add9d9e5 100644 (file)
@@ -59,19 +59,12 @@ protected:
 
     void doComputeBounds() Q_DECL_OVERRIDE;
 private:
-
-
-
-    FGAirportRef m_airport;
-
     struct RunwayData {
         QPointF p1, p2;
         int widthM;
         FGRunwayRef runway;
     };
 
-    QVector<RunwayData> m_runways;
-
     struct TaxiwayData {
         QPointF p1, p2;
         int widthM;
@@ -82,25 +75,18 @@ private:
         }
     };
 
-    QVector<TaxiwayData> m_taxiways;
-    QVector<QPainterPath> m_pavements;
-
     struct ParkingData
     {
         QPointF pt;
         FGParkingRef parking;
     };
 
-    QVector<ParkingData> m_parking;
-
     struct HelipadData
     {
         QPointF pt;
         FGHelipadRef helipad;
     };
 
-    QVector<HelipadData> m_helipads;
-
     void buildTaxiways();
     void buildPavements();
 
@@ -113,11 +99,26 @@ private:
 
     void drawHelipads(QPainter *painter);
 
+    QPainterPath pathForRunway(const RunwayData &r, const QTransform &t) const;
+    QPainterPath pathForHelipad(const HelipadData &h, const QTransform &t) const;
+    QPainterPath pathForParking(const ParkingData &p, const QTransform &t) const;
+
+private:
+    FGAirportRef m_airport;
+
+    QVector<RunwayData> m_runways;
+    QVector<TaxiwayData> m_taxiways;
+    QVector<QPainterPath> m_pavements;
+    QVector<ParkingData> m_parking;
+    QVector<HelipadData> m_helipads;
+
     QPainterPath m_parkingIconPath, // arrow points right
         m_parkingIconLeftPath; // arrow points left
     double m_approachDistanceNm;
     FGRunwayRef m_selectedRunway;
     FGParkingRef m_selectedParking;
+
+    QPixmap m_helipadIcon;
 };
 
 #endif // of GUI_AIRPORT_DIAGRAM_HXX